Context与Store结合

借助于context的跨级通信能力,可以将store管理数据的模式应用于每个组件当中。即将store通过context传递到子组件,一方面子组件可以通过store.dispatch()触发store中数据更新,另一方面子组件可以通过store.getState()方法获取最终的更新状态,刷新UI。
Redux解读
React之Context
1.目录结构
在这里插入图片描述
制作一个更换主题色的App
参考【结合 context 和 store
store.js

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
  }
}

export default createStore(themeReducer)

Index.js
引入store,通过context将store传递给子组件。

import React, { Component } from 'react'
import Header from './Header'
import Content from './Content'
import PropTypes from 'prop-types';
import store from '../react-redux/store';

class Index extends Component {

  static childContextTypes = {
    store: PropTypes.object
  }


  getChildContext(){
    return { store }
  }

  render () {
    return (
      <div>
        <Header />
        <Content />
      </div>
    )
  }
}
export default Index;

Header.js
获取到store,获取状态中的值

import React, { Component } from 'react'
import PropTypes from 'prop-types'

class Header extends Component {

  static contextTypes = {
    store: PropTypes.object
  }

  constructor(props){
    super(props);

    this.state = {
      theme: {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 () {
    console.log(this.context)
    return (
      <h1 style={{ color: this.state.themeColor }}>更换主题色</h1>
    )
  }
}

export default Header

Content.js
获取context中store的状态值,更新UI,同上类似的逻辑。

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import ThemeSwitch from './ThemeSwitch'

class Content extends Component {
  render () {
    return (
      <div>
        <p>React.js 小书内容</p>
        <ThemeSwitch />
      </div>
    )
  }
}

export default Content

ThemeSwitch.js
调用store.dispatch方法去更新store。

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('red')}>Red</button>
        <button onClick={()=>this.handleSwitchColor('blue')}>Blue</button>
      </div>
    )
  }
}

export default ThemeSwitch

小结:
如上代码虽然功能点特别简单,但是会发现每个子组件都在写重复的代码,获取context,通过store更新数据,更新UI。
react-redux中的connect函数可以让你从上述繁重的工作中解放出来。在了解connect之前,有必要先了解一下高阶组件。

借助于高阶组件,Header.jsContent.js中的获取contextstore的代码逻辑完全可以复用,你只需要将组件作为参数传入即可。

同时connect函数还具有将state转换成props的能力(mapStateToProps),自己的组件只需要关注props获取数据更新UI即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青菜小王子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值