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 }}></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 }}></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
标签:themeColor,const,mapStateToProps,React,state,import,return,redux,store From: https://www.cnblogs.com/mounterLove/p/18075903