低配版的Redux

133 阅读1分钟

手写低配版Redux的Provider

import React,{PureComponent} from 'react'
import {StoreContext} from './context'

export default function connect(mapStateToProps,mapDispatchToProps){
 return function enHanceHOC(WrapperComponent) {
   class EnhanceComponent extends PureComponent{
     constructor(props,context){
       super(props,context)
       this.state = {
        //  store.getState() 响应式获取最新数据
         storeState:mapStateToProps(context.getState())
        //  这里不能直接使用 this.context时是没有值的 例如 props 没有主动去继承 是react后面自己赋值的
       }
     }

     componentDidMount() {
       this.unsubscribe = this.context.subscribe(() => {
          this.setState({
            storeState:mapStateToProps(this.context.getState())       
          })
       })
     }

     componentWillUnmount() {
      //  取消订阅
       this.unsubscribe()
     }

     render(){
      //  将传入的参数传给这个组件 就可以在调用这个组件的地方使用 props 进行使用
       return <WrapperComponent {...this.props} 
                                {...mapStateToProps(this.context.getState())} 
                                {...mapDispatchToProps(this.context.dispatch)}/>
     }
   }
   EnhanceComponent.contextType = StoreContext;
   return EnhanceComponent;
 }
}

./context

import React from 'react'

const StoreContext = React.createContext();

export {
  StoreContext
}

使用

index.js

import {StoreContext} from './utils/context'
import store from '../../store'
export default class App extends PureComponent {
  render() {
    return (
      <StoreContext.Provider value={store}>
        App
        <Home/>
        <About/>
      </StoreContext.Provider>
    )
  }
}

Home.js

import React  from 'react'
import {addAction,subAction} from '../../store/actionCreators'
import connect from '../../utils/connect'

function Cart(props) {
    return (
      <div>
        Cart
        <h2>当前计数:{props.counter}</h2>
        <button onClick={e => props.add(1)}>+1</button>
        <button onClick={e => props.sub(1)}>-1</button>
      </div>
    )
}

const mapStateToProps = state => {
  // 监听我们数据的改变
  return {
    counter:state.counter
  }
}

// 派发dispatch()
const mapDispatchToProps = dispatch => {
  return {
    add:function(n) {
      dispatch(addAction(n))
    },
    sub:function(n) {
      dispatch(subAction(n))
    }
  }
}

export default connect(mapStateToProps,mapDispatchToProps)(Cart)