dispatch 的代理工作
在 src/ThemeSwitch.js
中,ThemeSwitch 组件通过 store 的 dispatch 方法实现了数据的更改,这也导致了组件的强耦合。
我们的思路是让高阶组件 Connect 代替 ThemeSwitch 来实现 dispatch 功能,同时通过 props 将方法传递给 ThemeSwitch 组件。
修改 src/react-redux.js
文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| export const connect = (mapState2Props, mapDispatch2Props)=>(OriginComponent)=>{ class Connect extends Component {
componentWillMount(){ this._updateProps() }
_updateProps(){ const {store} = this.context
let stateProps = mapState2Props? mapState2Props(store.getState(), this.props) : {} let dispatchProps = mapDispatch2Props? mapState2Props(store.dispatch, this.props) : {}
this.setState({ allProps: { ...stateProps, ...dispatchProps, ...this.props } }) store.subscribe(this._updateProps.bind(this)) }
}
|
定义 mapDispatch2Props 函数
在 src/ThemeSwitch.js
文件中定义 mapDispatch2Props 函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import React, { Component } from 'react' import PropTypes from 'prop-types' import {connect} from './react-redux'
class ThemeSwitch extends Component { static propTypes = { themeColor: PropTypes.string, handleThemeSwitchClick: PropTypes.func }
render() { return ( <div> <button style={{color: this.props.themeColor}} onClick={this.props.handleThemeSwitchClick.bind(this, 'red')} >Red</button> <button style={{color: this.props.themeColor}} onClick={this.props.handleThemeSwitchClick.bind(this, 'blue')} >Blue</button> </div> ) } }
const mapState2Props = (state)=>{ return { themeColor: state.themeColor } }
const mapDispatch2Props = (dispatch)=>{ return { handleThemeSwitchClick : function(color){ dispatch({ type: 'CHANGE_COLOR', themeColor: color })} } }
ThemeSwitch = connect(mapState2Props, mapDispatch2Props)(ThemeSwitch)
export default ThemeSwitch;
|
这样 ThemeSwitch 组件的代码就变得非常整洁,而且扩展性也大大提高。