react-redux原理

使用react-redux 怎们能不了解原理,彻底了解原理和单纯的使用,应该不是一个级别的选手吧

redux原理实现

  • 简单的redux
    // 根据我们使用redux的用法 ,开始是createStore然后createStore中有getState、dispatch、subscribe
    
    // createStore 有两个参数 第一个reducer 第二个参数中间件 (增强)
    import React from "react";
    
    export function createStore(reducer, enhancer) {
        let currentState ; //初始状态 可以是对象或者什么都可以,因为使用时会给出初始值
        let currentListeners = []; //每次函数的修改都要触发组件的变化 ,所以要有监听器
        function getState() {    // 定义getState方法,getState()返回当前的state树,它与 store 的最后一个 reducer 返回值相同。
            return currentState;
        }
        function subscribe(listener) {  //定义我们监听的时候使用的方法
            currentListeners.push(listener)  // 将我们需要监听的组件传递进来,push到currentListeners数组中
        }
        function dispatch(action) {   //定义我们的dispatch方法  使用dispatch会传递一个action参数
            currentState = reducer(currentState,action);  
            // reducer 中有两个参数  像这样 counterReducer = (state=0,action)=>{ } reducer返回的新的state
            currentListeners.forEach(value => value()); 
            // 每次dispatch都执行一下 所有 subscribe里的内容 ,比如index.js中 每一次dispatch都执行render= ()=>{}这个方法
            // const render =()=>{
            //     ReactDOM.render(
            //         <App />,
            //         document.getElementById('root')
            //     );
            // };
            // render();
            // store.subscribe(render);
            return action
        }
        dispatch({type:'@IMOOC/WONIU-REDUX'});  //手动先dispatch ,让它第一次dispatch命中默认初始值dispatch,不然不会有初始值
        return {getState,subscribe,dispatch}
    }
    复制代码
  • react-redux
    • Provider

      Provider 模块功能并不复杂 ,需要实现一下两点

      • 在原应用组件上包裹一层,使原来整个应用成为Provider的子组件
      • 接收Redux的store作为props,通过context对象传递给子孙组件上的connect
      import React,{Component} from 'react'
      import PropTypes from 'prop-types'  
      //  prop-types就是对react组件中props对象中的变量进行类型检测的,因为props是react数据流的管道,我们通过prop-types就可以轻松监控react里大多数据的变量类型
      export class Provider extends Component{
          static childContextTypes = {  // 设置childContext 状态值类型
              store: PropTypes.object
          };
          getChildContext(){   // 设置childContext,设置完了这样所有的子元素都能取到
              return {store:this.store}
          }
          constructor(props, context){
              super(props, context);
              this.store = props.store  
          }
          render(){
              return this.props.children  // this.props.children是react内置在this.props上的对象,用于获取当前组件的所有子组件
          }
      }
      // Provider初始化时,获取到props中的store对象;
      // 将外部的store对象放入context对象中,使子孙组件上的connect可以直接访问到context对象中的store。
      // context可以使子孙组件直接获取父级组件中的数据或方法,而无需一层一层通过props向下传递。
      // context对象相当于一个独立的空间,父组件通过getChildContext()向该空间内写值;定义了contextTypes验证的子孙组件可以通过this.context.xxx,从context对象中读取xxx字段的值。
      
      复制代码
    • connect

      //添加监听对象,并尝试通过 props 将状态传递给子组件
      const connect = (mapStateToProps,mapDispatchToProps)=>{ //返回一个函数
          return WrappedComponent=>{
              return class ConnectComp extends Component{
                  static contextTypes = {
                      store:PropTypes.object
                  };
                  //获取context
                  constructor(props,context){
                      super(props, context)
                      this.state = {
                          props:{}  // 手动定义一个state
                      }
                  }
                  componentDidMount(){
                      const {store} = this.context
                      store.subscribe(()=>this.update())  // 每次dispatch(更新)都会执行一下subscribe 里边的
                      this.update()  //
                  }
                  update(){
                      const {store} = this.context;
                      const stateProps =mapStateToProps(store.getState())
                      const dispatchProps = bindActionCreators(mapDispatchToProps,store.dispatch)
                      //作用是将单个或多个ActionCreator转化为dispatch(action)的函数集合形式。
                      //将一个或多个action和dispatch组合起来生成mapDispatchToProps需要生成的内容 ,其实就是把多个action还是用dispatch调用
                      this.setState({
                          props:{
                              ...this.state.props,
                              ...stateProps,
                              ...dispatchProps
                          }
                      })
                  }
                  render() {
                      return <WrappedComponent {...this.state.props}></WrappedComponent>
                      // 这个WrappedComponent也就是我们的使用的App,这样的connect(mapStateToProps,mapDispatchToProps)(App)
                      // 使用connect组件的时候 我们的state add方法等等都到了props之上,就是通过这实现的
                  }
              }
          }
      }
      复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享