在上一节中todolist使用react-redux加上中间件对todolist做了一个优化,使代码扩展性更强,但是在UI组件中存在大量的函数方法和方法的绑定以及props传值,如下:
import React, {Component, Fragment} from "react";
import store from "./store";
import {getDeleteItemClick, getInputChange, getSubmitClick, getTodoList} from "./store/actionCreates";
import AppUI from "./AppUI";
import {Provider} from 'react-redux'
class App extends Component {
constructor(props) {
super(props);
this.inputChange = this.inputChange.bind(this);
this.dataChange = this.dataChange.bind(this);
this.buttonClick = this.buttonClick.bind(this);
this.deleteClick = this.deleteClick.bind(this);
this.state = store.getState();
store.subscribe(this.dataChange)
}
render() {
return (
<Provider store={store}>
<AppUI
inputChange={this.inputChange}
dataChange={this.dataChange}
buttonClick={this.buttonClick}
deleteClick={this.deleteClick}
list={this.state.list}
inputValue={this.state.inputValue}
/>
</Provider>
);
}
dataChange() {
this.setState(store.getState());
}
inputChange(e) {
let action = getInputChange(e.target.value);
store.dispatch(action);
}
buttonClick() {
if (this.state.inputValue === '') return;
let action = getSubmitClick();
store.dispatch(action);
}
deleteClick(index) {
let action = getDeleteItemClick(index);
store.dispatch(action);
}
componentDidMount() {
let action = getTodoList();
store.dispatch(action)
}
}
export default App;
这样如果props传值比较深的情况每个UI组件都需要写上传值的props内容,另外太多的函数看起来也不美观,bind函数写起来也太繁琐,对于大型项目来说就不太适应了,这是需要用到react-redux的connect函数了,他不需要UI组件一级一级传值,自动dispach事件和接受state的改变。下面进一步优化:
1、设置根容器的Provider
删除所以的store.dispache和传值等等逻辑,只留下UI组件。
import React from 'react'
import store from "./store";
import AppUI from "./AppUI";
import {Provider} from 'react-redux'
const App = () => {
return (
<Provider store={store}>
<AppUI/>
</Provider>
)
}
export default App;
2、导入connect
import {connect} from 'react-redux';
如果导入不进来,则需要添加react-redux:
yarn add react-redux
3、给变量赋值
const {inputChange, buttonClick, inputValue, deleteClick, list} = this.props;
将this.inputChange,this.buttonClick等等替换为变量
4、设置connect
export default connect(mapStateToProps, mapDispatchToProps)(AppUI);
5、设置UI变量的值映射到props里面
const mapStateToProps = (state) => { return { inputValue: state.inputValue, list: state.list } }
6、这是事件的执行
const mapDispatchToProps = (dispatch, ownProps) => { return { inputChange: (e) => { dispatch(getInputChange(e.target.value)) }, buttonClick: () => { dispatch(getSubmitClick()) }, deleteClick: (index) => { dispatch(getDeleteItemClick(index)) } } }
这样就改造完毕,改造后的内容如下:
import {Button, Input, List} from "antd";
import React from "react";
import 'antd/dist/antd.css';
import {connect} from 'react-redux';
import {getDeleteItemClick, getInputChange, getSubmitClick} from "./store/actionCreates";
class AppUI extends React.Component {
render() {
const {inputChange, buttonClick, inputValue, deleteClick, list} = this.props;
return (
<div style={{width: 200, padding: 10}}>
<Input placeholder="请输入内容……" onChange={inputChange} value={inputValue}/>
<Button type="primary" style={{marginTop: 10}} onClick={buttonClick}>提交</Button>
<List
style={{marginTop: 10}}
bordered
dataSource={list}
renderItem={(item, index) => (
<List.Item onClick={() => deleteClick(index)}>
{item}
</List.Item>
)}
/>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
inputValue: state.inputValue,
list: state.list
}
}
const mapDispatchToProps = (dispatch, ownProps) => {
return {
inputChange: (e) => {
dispatch(getInputChange(e.target.value))
},
buttonClick: () => {
dispatch(getSubmitClick())
},
deleteClick: (index) => {
dispatch(getDeleteItemClick(index))
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(AppUI);
运行结果和之前的一样:
源码地址:https://download.csdn.net/download/yoonerloop/14001179