先决条件 Reducer 概念
¥Prerequisite Reducer Concepts
如 "Redux 基础知识" 第 3 部分:状态、操作和 reducer 中所述,一个 Redux reducer 函数:
¥As described in "Redux Fundamentals" Part 3: State, Actions, and Reducers, a Redux reducer function:
应具有
(previousState, action) => newState
的签名,类似于你传递给Array.prototype.reduce(reducer, ?initialValue)
的函数类型¥Should have a signature of
(previousState, action) => newState
, similar to the type of function you would pass toArray.prototype.reduce(reducer, ?initialValue)
应该是 "pure",表示 reducer:
¥Should be "pure", which means the reducer:
不执行副作用(例如调用 API 或修改非本地对象或变量)。
¥Does not perform side effects (such as calling API's or modifying non-local objects or variables).
不调用非纯函数(如
Date.now
或Math.random
)。¥Does not call non-pure functions (like
Date.now
orMath.random
).不会改变它的参数。如果 reducer 更新状态,它不应该就地修改现有的状态对象。相反,它应该生成一个包含必要更改的新对象。对于 reducer 更新的状态内的任何子对象都应该使用相同的方法。
¥Does not mutate its arguments. If the reducer updates state, it should not modify the existing state object in-place. Instead, it should generate a new object containing the necessary changes. The same approach should be used for any sub-objects within state that the reducer updates.
关于不可变性、副作用和突变的注意事项
¥Note on immutability, side effects, and mutation
不鼓励突变,因为它通常会破坏时间旅行调试,以及 React Redux 的
connect
函数:¥Mutation is discouraged because it generally breaks time-travel debugging, and React Redux's
connect
function:
对于时间旅行,Redux DevTools 期望重放记录的操作会输出一个状态值,但不会更改任何其他内容。突变或异步行为等副作用将导致时间旅行改变步骤之间的行为,从而破坏应用。
¥For time traveling, the Redux DevTools expect that replaying recorded actions would output a state value, but not change anything else. Side effects like mutation or asynchronous behavior will cause time travel to alter behavior between steps, breaking the application.
对于 React Redux,
connect
检查从mapStateToProps
函数返回的 props 是否已更改,以确定组件是否需要更新。为了提高性能,connect
采用了一些依赖于状态不可变的捷径,并使用浅引用相等性检查来检测更改。这意味着通过直接突变对对象和数组所做的更改将不会被检测到,并且组件将不会重新渲染。¥For React Redux,
connect
checks to see if the props returned from amapStateToProps
function have changed in order to determine if a component needs to update. To improve performance,connect
takes some shortcuts that rely on the state being immutable, and uses shallow reference equality checks to detect changes. This means that changes made to objects and arrays by direct mutation will not be detected, and components will not re-render.其他副作用(例如在 reducer 中生成唯一 ID 或时间戳)也会使代码变得不可预测并且更难以调试和测试。
¥Other side effects like generating unique IDs or timestamps in a reducer also make the code unpredictable and harder to debug and test.
由于这些规则,在转向组织 Redux reducer 的其他特定技术之前,充分理解以下核心概念非常重要:
¥Because of these rules, it's important that the following core concepts are fully understood before moving on to other specific techniques for organizing Redux reducers:
Redux reducer 基础知识
¥Redux Reducer Basics
关键概念:
¥Key concepts:
从状态和状态形态的角度思考
¥Thinking in terms of state and state shape
按状态切片委派更新责任(Reducer 组合)
¥Delegating update responsibility by slice of state (reducer composition)
高阶 reducer
¥Higher order reducers
定义 reducer 初始状态
¥Defining reducer initial state
阅读清单:
¥Reading list:
纯函数和副作用
¥Pure Functions and Side Effects
关键概念:
¥Key Concepts:
副作用
¥Side effects
纯函数
¥Pure functions
如何从组合功能的角度思考
¥How to think in terms of combining functions
阅读清单:
¥Reading List:
不可变数据管理
¥Immutable Data Management
关键概念:
¥Key Concepts:
可变性与不可变性
¥Mutability vs immutability
安全地、不可变地更新对象和数组
¥Immutably updating objects and arrays safely
避免改变状态的函数和语句
¥Avoiding functions and statements that mutate state
阅读清单:
¥Reading List:
标准化数据
¥Normalizing Data
关键概念:
¥Key Concepts:
数据库结构和组织
¥Database structure and organization
将关系/嵌套数据拆分到单独的表中
¥Splitting relational/nested data up into separate tables
存储给定项目的单个定义
¥Storing a single definition for a given item
通过 ID 引用项目
¥Referring to items by IDs
使用以项目 ID 为关键字的对象作为查找表,并使用 ID 数组来跟踪排序
¥Using objects keyed by item IDs as lookup tables, and arrays of IDs to track ordering
将项目关联到关系中
¥Associating items in relationships
阅读清单:
¥Reading List: