Redux 101
Redux是什么?
Redux 是一个可预测的状态管理库,旨在帮助您编写在客户端、服务器和原生环境中行为一致且易于测试的 JavaScript 应用程序。
为什么要考虑使用 Redux?
根据 Redux 官方文档:
Redux 帮助你管理“全局”状态——应用程序的许多部分都需要的状态。
Redux 提供的模式和工具让您更容易理解应用程序状态何时、何地、为何以及如何更新,以及当这些更改发生时应用程序逻辑将如何运行。Redux 引导您编写可预测且可测试的代码,从而帮助您确信应用程序将按预期运行。
Redux试图解决什么问题?
Redux 想要解决的问题是可预测的状态更新,因为了解状态在哪里以及为什么发生变化,并拥有“单一数据源”会是一个优势。
Redux 让你能够轻松地调试应用程序,它是如何做到的呢?
它将 UI 层与数据分离,这有助于你随时了解应用程序的运行情况。
Redux的主要原则是什么?
我们可以将 Redux 的设计意图概括为三个核心概念:

1.单一数据源:
应用程序中所有变化的内容(数据、用户界面)状态都包含在单个对象(*状态树/存储*)中。
商店的初始状态由您决定,但它通常是一个对象(类似于模型),并且不需要 setter 来进行初始设置。
店铺:
一个保存应用程序整个状态树的对象,它包含以下几个方法:
getState()dispatch(action)subscribe(listener)replaceReducer(nextReducer)
我们稍后会详细讨论这家商店及其运营方式。
如何创建你的 Redux store?
将你的根 reducer 函数传递给 createStore,像这样:
const userReducer = function(state = [], action) {
if (action.type === 'ADD_USER') {
var newState = state.concat([action.user]);
return newState;
}
return state;
}
const store = createStore(users, ['Use Redux'])
store.dispatch({
type: 'ADD_USER',
user: {name: 'Rawan', language: 'EN'}
})
createStore(reducer, [preloadedState], [enhancer])
我们现在只会讨论“preloadedState”,稍后会解释 reducer。
[preloadedState]:应用程序的初始状态。

2.状态是只读的。
状态树是只读的,改变状态(将数据从应用程序发送到 Redux store)的唯一方法是分发一个action,如下所示:
const action = {
type: 'ADD_USER',
user: {name: 'Rawan', language: 'EN'}
};
store.dispatch(action);
执行一个动作意味着什么?
你可以把分发操作理解为在应用程序中“触发事件”。发生了某些事情,我们希望数据存储知道这件事。
行动:
这是一个描述更改的纯 JavaScript 对象,其中包含一个 type 字段,用于指示要执行的操作类型。type
字段应该是一个描述性字符串,格式为“domain/eventName”,例如“users/userLogin”。
动作对象可以包含其他字段,其中包含有关所发生事件的附加信息。我们称之为“有效载荷”。
const userLoginAction = {
type: 'users/USER_LOGIN',
payload: {
username: "Adam",
password: "pass1234"
}
}
如您所见,我们将操作声明为一个具有类型和有效负载的对象。
3.使用纯函数(Reducers)进行更改
为了指定如何通过分发的动作转换状态树,我们编写称为Reducers 的纯函数来实现这一点。
纯函数:
求和函数是指,给定相同的输入,始终返回相同的输出(状态),其返回值仅取决于参数的值。
例如:如果将 1 和 4 传递给求和函数,则始终会得到 5。
此外,纯函数不应有任何副作用,例如:
修改输入、网络调用、更改文件系统 (fs)、查询 DOM、设置异步计时器、修改函数外部的状态、修改函数的参数、生成随机数或唯一的随机 ID(例如 Math.random() 或 Date.now())……等等
减速器:
reducer 接受当前状态和action对象作为参数,并且只能通过返回新状态来修改状态。
正如 Redux 文档所述:
你可以把 reducer 看作是一个事件监听器,它会根据接收到的操作(事件)类型来处理事件。
Reducer 有 3 条重要规则:
- 应该只根据状态和动作参数计算新的状态值。
- 他们不得修改现有状态。
- 它们只能进行不可变更新,即复制现有状态并对复制的值进行修改。它们不得执行任何异步逻辑、计算随机值或产生其他“副作用”。
如你所见,reducer 的规则与纯函数的规则相同,但我们为什么要遵循这些规则呢?
-
代码可预测性是指,当一个函数的输出仅根据输入参数计算时,更容易理解该代码的工作原理并进行测试。
-
如果一个函数修改了其他值,包括它的参数(当前状态、操作),这可能会导致应用程序的运行方式发生意外变化。这可能是导致 bug 的常见原因,例如“我更新了状态,但现在我的 UI 却没有按预期更新!”
-
Redux DevTools 的一些功能依赖于 reducer 正确遵循这些规则。
综上所述,
Redux 将所有应用程序状态存储在一个名为“store”的单一数据源中。为了改变状态,组件可以“dispatch”一个 action 来改变 store 中的状态。然后,需要感知状态变化的组件可以“subscribe” store 来获取状态变化,如下所示:
最后,这里简要总结一下使用 Redux 的原理:
本文到此结束,这只是对 Redux 主要概念的简要介绍,希望你有所收获 :)
祝您编程愉快!
文章来源:https://dev.to/rawaneltobgy/redux-101-a5e
