react-redux实现TodoList。
项目结构图如下:

package.json
"devDependencies": {
"@babel/core": "^7.18.5",
"@babel/plugin-transform-runtime": "^7.18.5",
"@babel/preset-env": "^7.18.2",
"@babel/preset-react": "^7.17.12",
"babel-loader": "^8.2.5",
"css-loader": "^6.7.1",
"css-minimizer-webpack-plugin": "^4.0.0",
"html-webpack-plugin": "^5.5.0",
"mini-css-extract-plugin": "^2.6.1",
"sass": "^1.52.3",
"sass-loader": "^13.0.0",
"style-loader": "^3.3.1",
"terser-webpack-plugin": "^5.3.3",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.9.2",
"webpack-merge": "^5.8.0"
},
"dependencies": {
"@babel/runtime": "^7.18.3",
"react": "^16.8.0",
"react-dom": "^16.8.0",
"react-router-dom": "^5.2.1",
"redux": "^4.2.0",
"redux-thunk": "^2.4.0",
"axios": "^0.27.2",
"react-redux": "^5.1.2"
}
Input.js
import React, { Component } from 'react'
export default class Input extends Component {
render() {
let {width,height,size,defaultValue} = this.props
return (
<input style={{
width: width,
height: height,
fontSize: size
}}
value={defaultValue}
onChange={(event)=>{defaultValue= event.target.value;}}
onInput={this.handleInput.bind(this)}
onKeyPress={this.handleEnter.bind(this)}
/>
)
}
//输入事件
handleInput(e){
this.props.onInput(e.target.value)
}
//回车事件
handleEnter(e){
if(e.key === 'Enter'){
this.props.onEnter(e.target.value)
}
}
}
List.js
import React, { Component } from 'react'
export default class List extends Component {
render() {
return (
<ul>
{ this.showList() }
</ul>
)
}
//用于渲染li
showList(){
if(!this.props.data || this.props.data.length === 0) return <li>暂无数据</li>
return this.props.data.map((item,index)=>{
return (
<li key={index}>
{item}
<button onClick={this.handleUpdateClick.bind(this,index,item)}>修改</button>
<button onClick={this.handleDelClick.bind(this,index,item)}>删除</button>
</li>
)
})
}
//删除按钮点击事件
handleDelClick(index,item){
this.props.onDelete(index,item)
}
//修改按钮点击事件
handleUpdateClick(index,item){
this.props.onUpdate(index,item)
}
}
store/typeName.js
const CHANGE_VALUE = 'CHANGE_VALUE'
const ADD_LIST = 'ADD_LIST'
const UPDATE_LIST = 'UPDATE_LIST'
const DELETE_LIST = 'DELETE_LIST'
const typeNames = {
CHANGE_VALUE,
ADD_LIST,
UPDATE_LIST,
DELETE_LIST
}
export default typeNames
store/reduxmap.js
import tn from './typeName'
//提供state数据的映射
function mapStateToProps(state){
return {
inputValue: state.inputValue,
list: state.list
}
}
//提供操作dispatch的函数映射
function mapDispatchToProps(dispatch) {
return {
changeValue(val){ //输入框的改变事件
let action = {
type: tn.CHANGE_VALUE,
inputValue: val
}
dispatch(action)
},
addList(val){ //添加元素事件,即Input组件的回车事件
let action = {
type: tn.ADD_LIST,
inputValue: val
}
dispatch(action)
},
updateListItem(index){ //修改元素
let value = prompt('请输入:')
if(!value) return
let action = {
type: tn.UPDATE_LIST,
value,
index
}
dispatch(action)
},
deleteListItem(index){ //删除元素
let action = {
type: tn.DELETE_LIST,
index
}
dispatch(action)
}
}
}
const mapFunction = {
mapStateToProps,
mapDispatchToProps
}
export default mapFunction
store/reducer.js
import tn from './typeName'
let defaultState = {
inputValue: '',
list: []
}
let reducer = (state = defaultState, action) => {
//更新输入的值
if(action.type === tn.CHANGE_VALUE){
let tempState = JSON.parse(JSON.stringify(state))
tempState.inputValue = action.inputValue
return tempState
}
//添加数据
if(action.type === tn.ADD_LIST){
let tempState = JSON.parse(JSON.stringify(state))
tempState.list.push(action.inputValue)
tempState.inputValue = ''
return tempState
}
//更新数据
if(action.type === tn.UPDATE_LIST){
let tempState = JSON.parse(JSON.stringify(state))
tempState.list.splice(action.index,1,action.value)
return tempState
}
//删除数据
if(action.type === tn.DELETE_LIST){
let tempState = JSON.parse(JSON.stringify(state))
tempState.list.splice(action.index,1)
return tempState
}
return state
}
export default reducer
store/index.js
import {legacy_createStore as createStore} from 'redux'
import reducer from './reducer'
let store = createStore(reducer)
export default store
App.js
import React, { Component } from 'react'
import { connect } from 'react-redux'
import map from './store/reduxmap'
import Input from './Input'
import List from './List'
class App extends Component {
render() {
let { inputValue, list, changeValue, addList, updateListItem, deleteListItem } = this.props
return (
<div>
<Input defaultValue={inputValue}
onInput={changeValue}
onEnter={addList}
/>
<List data={list}
onUpdate={updateListItem}
onDelete={deleteListItem}
/>
</div>
)
}
}
export default connect(map.mapStateToProps, map.mapDispatchToProps)(App)
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'
import {Provider} from 'react-redux'
import store from './store'
ReactDOM.render(
<Provider store={store}>
<App></App>
</Provider>
,document.getElementById('root'));
运行效果:
