動手實現 React-redux(二)mapDispatchToProps
阿新 • • 發佈:2018-12-14
App.js:
import React, { Component } from 'react'; import PropTypes from 'prop-types' import Header from './Header' function createStore (reducer) { let state = null const listeners = [] const subscribe = (listener) => listeners.push(listener) const getState = () => state const dispatch = (action) => { state = reducer(state, action) listeners.forEach((listener) => listener()) } dispatch({}) // 初始化 state return { getState, dispatch, subscribe } } const themeReducer = (state, action) => { if (!state) return { themeColor: 'red' } switch (action.type) { case 'CHANGE_COLOR': return { ...state, themeColor: action.themeColor } default: return state } } const store = createStore(themeReducer) class App extends Component { static childContextTypes = { store: PropTypes.object } getChildContext () { return { store } } render() { return ( <div> <Header /> </div> ); } } export default App;
Header.js:
import React, { Component } from 'react'; import PropTypes from 'prop-types' import { connect } from './react-redux' import ThemeSwitch from './ThemeSwitch' class Header extends Component { static propTypes = { themeColor: PropTypes.string } render () { return ( <div> <h1 style={{ color: this.props.themeColor }}>xutongbao</h1> <ThemeSwitch/> </div> ) } } const mapStateToProps = (state) => { return { themeColor: state.themeColor } } Header = connect(mapStateToProps, null)(Header) export default Header
react-redux.js:
import React, { Component } from 'react' import PropTypes from 'prop-types' export const connect = (mapStateToProps, mapDispatchToProps) => (WrappedComponent) => { class Connect extends Component { static contextTypes = { store: PropTypes.object } constructor () { super() this.state = { allProps: {} } } componentWillMount () { const { store } = this.context this._updateProps() store.subscribe(() => this._updateProps()) } _updateProps () { const { store } = this.context let stateProps = mapStateToProps ? mapStateToProps(store.getState(), this.props) : {} // 防止 mapStateToProps 沒有傳入 let dispatchProps = mapDispatchToProps ? mapDispatchToProps(store.dispatch, this.props) : {} // 防止 mapDispatchToProps 沒有傳入 this.setState({ allProps: { ...stateProps, ...dispatchProps, ...this.props } }) } render () { return <WrappedComponent {...this.state.allProps} /> } } return Connect }
ThemeSwitch.js:
import React, { Component } from 'react';
import PropTypes from 'prop-types'
import { connect } from './react-redux'
class ThemeSwitch extends Component {
static contextTypes = {
store: PropTypes.object
}
handleSwitchColor (color) {
if (this.props.onSwitchColor) {
this.props.onSwitchColor(color)
}
}
render () {
return (
<div>
<button onClick={this.handleSwitchColor.bind(this, 'red')}>Red</button>
<button onClick={this.handleSwitchColor.bind(this, 'blue')}>Blue</button>
</div>
)
}
}
const mapDispatchToProps = (dispatch) => {
return {
onSwitchColor: (color) => {
dispatch({ type: 'CHANGE_COLOR', themeColor: color })
}
}
}
ThemeSwitch = connect(null, mapDispatchToProps)(ThemeSwitch)
export default ThemeSwitch