准备工作
TodoList组件
import React,{Component, Fragment} from 'react';
import 'antd/dist/antd.css';
import { Input,Button,List } from 'antd';
import { UserOutlined } from '@ant-design/icons';
class TodoList extends Component{
render(){
return (
<Fragment>
<div style={{marginTop:'10px',marginLeft:'10px'}}>
<Input size="large" placeholder="请输入..." prefix={<UserOutlined />}
style={{width:'300px',marginRight:'10px'}}
/>
<Button type="primary" style={{height:'39px'}}>提交</Button>
</div>
<List
style={{width:'300px',marginTop:'10px',marginLeft:'10px'}}
size="small"
bordered
dataSource={[]}
renderItem={(item) => <List.Item>{item}</List.Item>}
/>
</Fragment>
);
}
}
export default TodoList;
挂载到页面上
./store/reducer.js
./store/index.js
OK~react-redux开始
首先安装react-redux
在入口文件中引入store以及react-redux的Provider组件
利用为Provider添加store属性之后,Provider下面的所有组件都可以连接store
import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList';
import {Provider} from 'react-redux';
import store from './store';
const App=(
<Provider store={store}>
<TodoList/>
</Provider>
);
ReactDOM.render(App,document.getElementById('root'));
接下来到TodoList中去通过connect方法按照一定的规则(通过参数传递)连接store
connect方法可传递两个参数:mapStateToProps和mapDispatchToProps
export default connect(mapStateToProps,mapDispatchToProps)(TodoList);
mapStateToProps将store中的数据映射到当前组件的props中,这样一来,就可以直接通过this.props.list使用store中的list,inputValue同理
const mapStateToProps=(state)=>{
return {
value:state.inputValue,
list:state.list
}
}
这样便将store中的数据用到TodoList组件中啦
但是现在的输入框还不能输入,因此我们要为输入框绑定事件并传递action给store,再给reducer处理
此时事件处理函数就可以放在connect的第二个参数mapDispatchToProps中去写了
它作用是将store.dispatch方法映射到当前组件的props中,这样便可直接使用dispatch参数传递action
const mapDispatchToProps=(dispatch)=>{
return {
handleChange(e){
const action={
type:'handle_change',
value:e.target.value
}
dispatch(action);
}
}
}
reducer处理数据
let func=(state=defaultState,action)=>{
if(action.type==='handle_change'){
const newState=JSON.parse(JSON.stringify(state));
newState.inputValue=action.value;
return newState;
}
return state;
}
现在输入框便可以输入内容了,这样就无需使用store.subscribe监听store的数据变化再做替换了
接下来也是同样的道理实现添加和删除功能,就不再多说啦
然后connect方法将todolist这个ui组件和数据和业务逻辑结合,返回的就是一个容器组件了
最后来做一些优化:定义actionTytpes、利用actionCreator统一创建action、对props对象解构赋值、由于组件只有一个render函数,把它处理成一个无状态组件,提升性能
TodoList.js
import React,{Fragment} from 'react';
import 'antd/dist/antd.css';
import { Input,Button,List } from 'antd';
import { UserOutlined } from '@ant-design/icons';
import {connect} from 'react-redux';
import {getChangeAction,getClickAction,getRemoveAction} from './store/actionCreator';
let TodoList=(props)=>{
const {value,list,handleChange,handleClick,removeItem} =props;
return (
<Fragment>
<div style={{marginTop:'10px',marginLeft:'10px'}}>
<Input value={value} size="large" placeholder="请输入..." prefix={<UserOutlined />}
style={{width:'300px',marginRight:'10px'}}
onChange={handleChange}
/>
<Button type="primary" style={{height:'39px'}}
onClick={handleClick}
>提交</Button>
</div>
<List
style={{width:'300px',marginTop:'10px',marginLeft:'10px'}}
size="small"
bordered
dataSource={list}
renderItem={(item,index) => <List.Item onClick={()=>{
removeItem(index);
}}>{item}</List.Item>}
/>
</Fragment>
);
}
const mapStateToProps=(state)=>{
return {
value:state.inputValue,
list:state.list
}
}
const mapDispatchToProps=(dispatch)=>{
return {
handleChange(e){
const action=getChangeAction(e.target.value);
dispatch(action);
},
handleClick(){
const action=getClickAction();
dispatch(action);
},
removeItem(index){
const action=getRemoveAction(index);
dispatch(action);
}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(TodoList);
reducer.js
import {HANDLE_CHANGE,HANDLE_CLICK,REMOVE_ITEM} from './actionTypes';
const defaultState={
inputValue:'',
list:['Amethyst']
}
let func=(state=defaultState,action)=>{
if(action.type===HANDLE_CHANGE){
const newState=JSON.parse(JSON.stringify(state));
newState.inputValue=action.value;
return newState;
}
if(action.type===HANDLE_CLICK){
const newState=JSON.parse(JSON.stringify(state));
newState.list.push(state.inputValue);
newState.inputValue='';
return newState;
}
if(action.type===REMOVE_ITEM){
const newState=JSON.parse(JSON.stringify(state));
newState.list.splice(action.value,1);
return newState;
}
return state;
}
export default func;
效果如下: