• React-Redux 总结


    一、定义与功能

    React-Redux 将所有组件分成两大类:UI 组件(presentational component)和容器组件(container component)

    1、UI 组件特征:

    • 只负责 UI 的呈现,不带有任何业务逻辑
    • 没有状态(即不使用this.state这个变量)
    • 所有数据都由参数(this.props)提供
    • 不使用任何 Redux 的 API

    2、容器组件特征:

    • 负责管理数据和业务逻辑,不负责 UI 的呈现
    • 带有内部状态
    • 使用 Redux 的 API

    总结:

      UI 组件负责 UI 的呈现,容器组件负责管理数据和逻辑。

      React-Redux 规定,所有的 UI 组件都由用户提供,容器组件则是由 React-Redux 自动生成。也就是说,用户负责视觉层,状态管理则是全部交给它。

    二、使用与方法

    1、connect方法  输入UI组件, 输出容器组件

    React-Redux 提供connect方法,用于从 UI 组件生成容器组件。

    // TodoList-> UI组件; VisibleTodoList -> 容器组件
    // mapStatetoProps,mapDispatchToProps -> 它们定义了 UI 组件的业务逻辑。
    // mapStatetoProps 可省略,若省略,UI 组件就不会订阅Store,就是说 Store 的更新不会引起 UI 组件的更新
    import { connect } from 'react-redux'
    const VisibleTodoList = connect(mapStatetoProps, mapDispatchToProps)(TodoList); 

    (1)  mapStateToProps(state [,props]) 负责输入逻辑,即将state映射到 UI 组件的参数(props

    state: 必选,state对象;props: 可选,代表容器组件的props对象
    mapStateToProps会订阅 Store,每当state更新的时候,就会自动执行,重新计算 UI 组件的参数(props),从而触发 UI 组件的重新渲染。

    // map Redux state to component props (把 Redux state 映射到 component props)
    const mapStatetoProps = (state) => {
       return {num: state}
    }
    // 使用ownProps作为参数后,若容器组件的参数(ownProps)发生变化,也会引发 UI 组件重新渲染
    const mapStateToProps = (state, ownProps) => {
      return {
        active: ownProps.filter === state.visibilityFilter
      }
    }

    (2) mapDispatchToProps 负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。

    // map Redux actions to component props (把 Redux actions 映射到 component props)
    const mapDispatchToProps = dispatch => {
      return {
        onIncreaseClick: () => dispatch(increaseAction)
      };
    }

    mapDispatchToProps 分为两种类型:函数和对象

    mapDispatchToProps是一个函数,会得到dispatchownProps(容器组件的props对象)两个参数。

    mapDispatchToProps作为函数,应该返回一个对象,该对象的每个键值对都是一个映射,定义了 UI 组件的参数怎样发出 Action

    const mapDispatchToProps = (
      dispatch,
      ownProps
    ) => {
      return {
        onClick: () => {
          dispatch({
            type: 'SET_VISIBILITY_FILTER',
            filter: ownProps.filter
          });
        }
      };
    }

    mapDispatchToProps是一个对象,键名是对应 UI 组件的同名参数,键值应该是一个函数,会被当作 Action creator ,返回的 Action 会由 Redux 自动发出

    const mapDispatchToProps = {
      onClick: (filter) => {
        type: 'SET_VISIBILITY_FILTER',
        filter: filter
      };
    }

      三、原理与流程

    为了让子组件能够获得context属性,React强制要求根组件(此处为Provider组件)提供getChildContext实例方法,以及类属性childContextTypes。而子组件想要获取context,也必须定义类级别的Counter. contextTypes属性。定义是双向的,如果缺少了任何一块,子组件都获取不到context属性。

    我认为父组件的那块定义是在Provider的代码中实现的,而子组件的那部分是在connect方法中实现的。

    因此connect方法为Counter组件添加的context属性实质上是由Provider传下来的,这样在mapStatesToProps方法里的state参数实质上就是this.context.store.getState()方法获得的。

    页面首次加载以及之后有互动行为之后整个逻辑的流程:

    (1)页面首次加载时,store里的初始state获取过程:
    createStore(reducers,defaultParams)的调用,其中reducers可以使一个reducer,也可是redux.combineReducers过的reducer的集合。

    createStore方法会对每个reducer去dispatch一个action.type=@@redux/INIT类型的action,而这个action一般在reducer的代码里不会被handle,直接掉入default块,于是就返回了state的初始状态。

    然后一般就会ReactDom.render()将应用渲染出来,每个子组件的容器组件通过传入this.context.store.getState()方法获得的state对象, 以及容器组件上自带的ownProps给mapStatesToProperties方法,来构建props,最后将props应用到子组件的UI组件上。

    (2)互动行为之后整个逻辑:

    当在子组件上发生交互行为,如click时,mapDispatchToProps会定义click触发时应该dispatch哪一个action的映射。
    然后store接收到这个action后会进行reduce,得到最新的state,然后再调用所有的子组件的mapStatesToProps方法生成新的props。
    最后对Provider进行重新渲染。当然上面的事件计算出来的很多state可能都不会发生变化,所以diff算法不会去修改这些没有发生变化的组件,因此性能也比较好。

     
  • 相关阅读:
    Web应用指纹识别
    同步I/O 和 异步I/O
    怎样找出自己定义标签的java类
    Android多线程文件下载器
    cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第三步---主角开跑&同一时候带着刚体
    记C++课程设计--学生信息管理系统
    iOS开发--从TQRichTextViewDemo中学会分析project
    九度oj题目&吉大考研10年机试题全解
    setOnFocusChangeListener的使用
    查看网络port占用
  • 原文地址:https://www.cnblogs.com/136asdxxl/p/8316645.html
Copyright © 2020-2023  润新知