Redux记录

本博客 hjy-xh,转载请申明出处

说明

Redux是一个使用叫做action的事件来管理和更新应用状态的模式和工具库,它以集中式Store的方式对整个应用中使用的状态进行集中管理,其规则确保状态只能以可预测的方式更新。

三大原则

  • 单一的数据源
    整个应用的state被存储在一棵object tree中,并且这个object tree只存在于唯一一个store中

  • State 是只读的
    改变state的方法就是触发actionaction是一个用于描述已发生事件的普通对象

  • 使用纯函数来执行修改
    为了描述action如何改变state tree,需要编写reducers

一些重要的概念

  • Action

    • Action是把数据从应用传到store的有效载荷。它是store数据的唯一来源
    • 一般来说会通过store.dispatch()action传到store
    • Action本质上JavaScript普通对象,约定action内必须使用一个字符串对象type字段来表示将要执行的动作
  • Action创建函数

    • Action创建函数就是生成action的方法,这样做将使action创建函数更容易被移植和测试
    1
    2
    3
    4
    5
    6
    function addTodo(text) {
    return {
    type: ADD_TODO,
    text
    }
    }
  • Reducer

    • Reducers指定了应用状态的变化如何响应actions并发送到store的,记住actions只是描述了有事情发生了这一事实,并没有描述如何更新state
    • reducer就是一个纯函数,接收旧的stateaction,返回新的state:(previousState, action) => newState
  • Store
    Store有以下职责:

    • 维持应用的state
    • 提供getState()方法获取state
    • 提供dispatch(action)方法更新state
    • 通过subscribe(listener)注册监听器,并能够能够其返回的函数注销监听器
  • Middleware

相对于Express或者KoamiddlewareRedux middleware被用于解决不同的问题,但其中的概念是类似的。它提供的是位于action被发起之后,到达reducer之前的扩展点。 你可以利用Redux middleware来进行日志记录、创建崩溃报告、调用异步接口或者路由等等。

数据流

Redux使用单向数据流

  • State描述了应用程序在特定时间点的状况
  • 基于state来渲染UI
  • 当发生某些事情时(例如用户点击按钮),state会根据发生的事情进行更新
  • 基于新的state重新渲染UI

将这些步骤分解为更详细的内容:

  • 初始启动

    • 使用最顶层的 root reducer 函数常见 Redux store
    • store 调用一次root reducer,并将返回值保存为它的初始 state
    • 当UI首次渲染时,UI组件访问 Redux store 的当前 state,并使用该数据来决定要呈现的内容。同时监听 store 的更新,以便它们可以知道 state 是否已更改
  • 更新环节

    • 应用程序中发生了某些事情,例如用户点击按钮
    • dispatch 一个 action 到 React store
    • store 用之前的 state 和当前的 action 再次运行 reducer 函数,并将返回值保存为新的 state
    • store 通知所有订阅过的UI,通知它们 store 发生更新
    • 每个订阅过 store 数据的UI组件都会检查它们需要的 state 部分是否被更新
    • 发现数据被更新的每个组件都强制使用新数据重新渲染,紧接着更新网页

一些疑问

  • Reducer的规则

    Reducer必须符合以下规则:

    • 仅使用state和action参数计算新的状态值

    • 禁止直接修改state。必须通过复制现有的state并对复制的值进行更改的方式来做不可变更新

    • 禁止任何异步逻辑、依赖随机值或导致其它副作用的代码

      为什么这些规则很重要?

    • Redux的目标之一是使代码可预测。当函数的输出仅根据输入参数计算时,更容易理解该代码的工作原理并对其进行测试

    • 如果一个函数依赖于自身之外的变量,或者行为随机,你永远不知道运行时它会发生什么

    • 如果一个函数 mutate 了其它对象,比如它的参数,这可能会意外地改变应用程序的工作方式

    • Redux DevTools 的一些功能取决于你的 reducer 是否正确遵循这些规则

参考

Redux 中文官网

Redux 中文文档