zoukankan      html  css  js  c++  java
  • React Redux

    写在前面

    在前面介绍了 Redux,并用原生的 Redux 配合 React 开发了一个 todo-list 小 demo。

    但是后来 React 的作者为了让 React 用户更好地使用 Redux 进行 React 的项目开发,在 Redux 的基础上封装了一个专用库:React-Redux。React-Redux 在 Redux 的基础上根据 React 的特性进行了优化,因此现在大部分的 React 的项目开发的状态管理工具都是 React-Redux,但使用 React-Redux 的前提还是要学会 Redux,因为 React-Redux 是在 Redux 的基础上提供了额外的一个方法和一个组件。

    React-Redux 的厉害之处不是说额外提供了一个方法和一个组件,而是其提出了一种新的开发思路。在仅仅使用 Redux 的过程中,我们的组件在获得 state 后要在组件内部代码中筛选出该组件需要的数据,在组件调用事件函数时 dispatch 改变状态的动作。而 React-Reudx 提供了一种新的思路,将组件划分为 UI 组件容器组件

    UI 组件仅仅负责界面的展示,不负责任何的数据处理操作,因此不能在 UI 组件里使用 Redux 的 API ,如 getState、dispatch 等等。那么 UI 组件应该如何使用动态的数据状态呢?答案是使用组件的 props 参数,UI 组件用到的所有数据都在 Props 中接收到。

    与 UI 组件相反,容器组件负责数据状态的获得和操作,处理业务逻辑,如 getState、dispatch 等,不负责 UI 的呈现。

    将处理数据的容器组件包裹住只负责页面呈现的 UI 组件,二者包裹在一起就形成了一个完整的带有数据业务逻辑的组件,这样一来,状态处理 和 UI 呈现分离,更容易管理状态和 UI 样式,代码更加结构化。

    那么 React-Redux 如何使用呢?

    1. connect 方法

    React-Redux 提供了 connect 方法用于将 UI 组件和 容器组件 组合起来。connect 是一个返回一个函数的方法。该方法接收两个参数:mapStateToPropsmapDispatchToProps,返回的函数接收一个 UI 组件,并返回一个已经包裹了 UI 组件的容器组件。包裹了 UI 组件的容器组件就是一个包含状态的完整的组件。

    因此其实将 UI 组件和 容器组件 分开来说不太合适,将 UI 组件通过 connect 方法包裹一层状态业务逻辑就是容器组件了,因此,在页面中加载组件时,不再是使用 UI 组件了,而是使用包裹了状态业务逻辑的 容器组件。

    那么这个状态的业务逻辑是如何告诉负责包裹 UI 组件的 connect 方法的呢? 就是通过给 connect 方法传递参数 mapStateToProps 和 mapDispatchToProps 实现的。

    const container =  connect(
        mapStateToProps,
        mapDispatchToProps
    )(VisibleTodoList)
    

    1.1 mapStateToProps

    mapStateToProps 字面意思就是映射状态到属性,就是说其负责将 Redux 中获得的状态 state 通过处理得到该组件需要的数据状态,然后映射到 UI 组件的 Props 属性上。

    这种映射方式就是通过对象的键值对实现的,但是如果 mapStateToProps 直接是一个对象,那在该对象中对 Redux 状态的获取还得通过 getState() 手动获取,既然肯定是要获取当前状态,不如 Reac-Redux 帮我们做好算了。因此 React-Redux 就将 mapStateToProps 规定为是一个返回对象的函数,该函数接收两个参数 stateownProps,其中 state 就是当前的状态,React-Redux 会在 Redux 的状态变化时自动调用 mapStateToPrps 的,并将当前的状态作为第一个参数传递。

    那么第二个参数 ownProps 是什么呢?听字母的意思就是自己的属性的意思,容器组件在页面中加载时,页面也可以通过属性的方式传递数据给该容器组件,就像之前组件接收属性作为 Props 一样,ownProps就是容器组件在使用时,通过组件传递属性的方式接收的自己的数据状态。

    因此我们知道,mapStateToProps 订阅了 Redux 的 store,当状态发生变化时会自动执行,重新计算数据,从而重新渲染页面。但是还有一种方式会使该函数重新执行,就是其依赖的 ownProps 发生变化时也会重新计算并渲染。

    通过在 connect 方法中传递 mapStateToProps,connect 方法就会将 mapStateToprops 函数返回的对象中的全部属性作为 connect 连接的 UI 组件的 Props 对象的属性传递给 UI 组件的。因此在 UI 组件中的 Props 可以直接拿到 mapStateToState 返回对象里的属性。

    要点总结:

    1. mapStateToProps 用于外部向 UI 组件传递数据状态

    2. mapStateToProps 是一个函数,接收 state 和 ownProps 两个参数

    3. mapStateToProps 返回一个对象,对象的全部属性可在其连接的 UI 组件的 Props 对象中拿到

    4. mapStateToProps 订阅了 store 和 ownProps

    const mapStateToProps = (state, ownProps)=>{
        return {
            todoList: getVisibleTodoList(state.todoList, state.filter)
        }
    }
    

    1.2 mapDispatchToProps

    mapStateToProps 是负责外部传递数据到 UI 组件内使用的,那如果 UI 组件想要改变外部状态的时候该怎么办呢?

    在 Redux 中就是通过在事件函数中使用 store.dispatch(action) 方法触发改变状态的动作。React-Redux 规定了,在 UI 组件中不要包含业务逻辑的处理,不要在 UI 组件中使用 Redux API。

    ok,那就将该事件处理函数定义在容器组件的业务逻辑层中,这负责 UI 组件向外传递数据操作的就是 mapDispatchToprops。

    mapDispatchToProps 字面意思就是映射派遣到属性。就是将 UI 组件中的事件处理函数映射到 UI 组件的 Props 对象中,UI 组件在注册事件回调函数时直接使用 Props 中传递来的事件处理函数值就可以。

    一般在 UI 组件的事件处理函数中都会涉及到对 Redux 中 state 的改变,因此会经常用到 store.dispatch,但是使用 dispatch 方法做的只有一件事就是接收一个 action 然后改变状态。因此 React-Redux 规定,mapDispatchToProps 可以是一个对象,也可以是一个函数。

    当 mapDispatchToProps 是一个对象时,键值对中的值必须是一个 Action Creator 函数。会由 React-Redux 自动 dispatch。 如下:

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

    当 mapDispatchToProps 是一个函数时,需要返回一对象,对象的键值对中的值必须是一个手动 dispatch 的函数。如下:

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

    要点总结:

    1. mapDispatchToProps 负责 UI 组件向外部传递数据操作。

    2. mapDispatchToProps 可以是一个对象,也可以是一个函数。

    3. mapDispatchToProps 对象或返回对象的属性可以在 UI 组件的 Props 中拿到

    2. <Provide> 组件

    使用 connect 方法生成的 容器组件 的正常使用依赖于 Redux 的仓库实例:store。因为有了 store ,容器组件才能在 mapStateToProps 中拿到 state 当前状态,在 mapDispatchToProps 中拿到 dispatch 方法。

    React-Redux 提供了 <Provide> 组件,用 <Provide> 组件包裹住一个组件,然后在 <Provide> 组件中传入 store 值,那么在 <Provide> 包裹的组件及其其所有后代组件都可以直接使用到 store,从而也都能顺利拿到 state 和 dispatch 方法了。<Provide> 就是用于传递局部的全局变量,类似上下文 context

    const store = createStore(reducer, applyMiddleware(thunk))
    ReactDOM.render(
      <Provider store={store}>
        <App />
      </Provider>,
      document.getElementById('root')
    );
    

    源码链接

    在了解了 React-Redux 的使用方法后,再重新做一遍 todo-list 项目,就会使得代码组织结构更加清晰了,代码结构如下:

    源码

    参考链接

    React-Redux 的用法

  • 相关阅读:
    使用Aspose.Cell控件实现Excel高难度报表的生成(三)
    使用Aspose.Cell控件实现Excel高难度报表的生成(二)
    使用Aspose.Cell控件实现Excel高难度报表的生成(一)
    利用Aspose.Word控件和Aspose.Cell控件,实现Word文档和Excel文档的模板化导出
    新中新身份证阅读器不显示图片
    spring security 3 自定义认证,授权示例
    Spring Security教程
    Spring Security3实现,权限动态获取
    mybatis 做 insert操作的时候返回插入的那条数据的id
    如何在spring中获取request对象
  • 原文地址:https://www.cnblogs.com/lovevin/p/13553964.html
Copyright © 2011-2022 走看看