1.结合 context 和 store
import React, { Component } from 'react'; import PropTypes from 'prop-types' 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 Header extends Component { static contextTypes = { store: PropTypes.object } constructor () { super() this.state = { themeColor: '' } } componentWillMount () { const { store } = this.context this._updateThemeColor() store.subscribe(() => this._updateThemeColor()) } _updateThemeColor () { const { store } = this.context const state = store.getState() this.setState({ themeColor: state.themeColor }) } render () { return ( <div> <h1 style={{ color: this.state.themeColor }}>xutongbao</h1> <ThemeSwitch /> </div> ) } } class ThemeSwitch extends Component { static contextTypes = { store: PropTypes.object } // dispatch action 去改变颜色 handleSwitchColor (color) { const { store } = this.context store.dispatch({ type: 'CHANGE_COLOR', themeColor: color }) } render () { return ( <div> <button onClick={this.handleSwitchColor.bind(this, 'red')}>Red</button> <button onClick={this.handleSwitchColor.bind(this, 'blue')}>Blue</button> </div> ) } } class App extends Component { static childContextTypes = { store: PropTypes.object } getChildContext () { return { store } } render() { return ( <div> <Header /> </div> ); } } export default App;
2.connect 和 mapStateToProps
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)(Header) export default Header
react-redux.js:
import React, { Component } from 'react' import PropTypes from 'prop-types' export const connect = (mapStateToProps) => (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(store.getState(), this.props) // 额外传入 props,让获取数据更加灵活方便 this.setState({ allProps: { // 整合普通的 props 和从 state 生成的 props ...stateProps, ...this.props } }) } render () { return <WrappedComponent {...this.state.allProps} /> } } return Connect }
ThemeSwitch.js
import React, { Component } from 'react'; import PropTypes from 'prop-types' class ThemeSwitch extends Component { static contextTypes = { store: PropTypes.object } // dispatch action 去改变颜色 handleSwitchColor (color) { const { store } = this.context store.dispatch({ type: 'CHANGE_COLOR', themeColor: color }) } render () { return ( <div> <button onClick={this.handleSwitchColor.bind(this, 'red')}>Red</button> <button onClick={this.handleSwitchColor.bind(this, 'blue')}>Blue</button> </div> ) } } export default ThemeSwitch
来源:https://www.cnblogs.com/xutongbao/p/9924773.html