動手實現react-redux

這篇文章主要講 react-redux的實現原理,同時更好的去理解 react中高階函數的應用

這裏主要實現Provider組件和connect函數,新建react-redux文件夾,裏面新建入口文件index.js,拋出對應組件和方法:react

// react-redux/index.js
export {
  Provider,
  connect
}

第一次使用react-redux的時候,就感受有點像使用React.Context,可是子組件內部又是經過props拿到的數據和方法,這裏面connect函數應該是作了處理,將stateactions從新包裝後傳給了子組件,因此第一步應該先建redux的的Context:redux

// context.js
import React from "react";
export default React.createContext();

緊接着建立 Provider.js文件:數組

//Provider.js
import React,{Component} from "react";
import ReduxContext from "./context";

export default class Provider extends Component {
  render(){
    return (
      <ReduxContext.Provider value={{ store: this.props.store }}>
        {this.props.children}
      </ReduxContext.Provider>
    )
  }
}

Provider.js拿到父組件傳過來的store,並把它交給Provider,方便向下傳遞,接着就是渲染子組件了。app

接下來建立connect.jsconnect會返回一個函數而且接收渲染的的組件:ide

//connect.js
export default function (mapStateToProps,mapDispatchToProps){
    return function(WrapperComponent){}
}

咱們知道返回的函數最終也是通過執行後再拋出去的,因此返回的應該是一個類組件或者一個函數組件,這裏用到類組件會比較合適,由於還要對訂閱的更新視圖函數進行銷燬操做,而後store能夠經過向下傳遞的context拿到:函數

//connect.js
import ReduxContext from './context'
import React, { Component } from 'react'
export default function (mapStateToProps, mapDispatchToProps) {
  return function (WrapperComponent) {
    return class extends Component {
      static contextType = ReduxContext
      constructor(props, context) {
        super(props);
        // 經過mapStateToProps 返回包裝後的state,這裏可方便用戶拿到想要的state,同時優化渲染的組件
        this.state = mapStateToProps(context.store.getState())
      }
      componentDidMount() {
          // 訂閱更新視圖
        this.unSubscribe = this.context.store.subscribe(() => {
          this.setState(mapStateToProps(this.context.store.getState()))
        })
      }
      componentWillUnmount() {
        // 註銷訂閱
        this.unSubscribe()
      }
    }
  }
}

render裏面經過傳參的方式,就能夠將store裏面的值和處理過的action傳給子組件了:優化

//connect.js
...
render() {
  // 處理綁定的action
  let actions = redux.bindActionCreator(mapDispatchToProps,this.context.store.dispatch);
  return <WrapperComponent {...this.state} {...actions} />
}
...
相關文章
相關標籤/搜索