本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
Store
Store 保存着整个应用的 状态树。改变其内部状态的唯一方式是在其上派发一个 action,这会触发 根 reducer 函数 计算新的状态。
Store 不是一个类,它只是一个包含若干方法的普通对象。
要创建 store,请将根 reducer 函数 传递给 Redux Toolkit 的 configureStore 方法,它将使用合理的默认配置设置 Redux store。(或者,如果您尚未使用 Redux Toolkit,可以使用原始的 createStore 方法,但我们强烈建议您 尽快迁移代码到 Redux Toolkit)
Store 方法
getState()
返回应用当前的状态树。该值等于 store 的 reducer 最后一次返回的结果。
返回值
(any):应用当前的状态树。
dispatch(action)
派发一个 action。这是触发状态变更的唯一方式。
store 的 reducer 函数会同步接收当前的 getState() 结果和给定的 action 作为参数进行调用。其返回值将被视为下一个状态,此后调用 getState() 将返回该值,且变更监听器会立即收到通知。
如果尝试在 reducer 内部调用 dispatch,会抛出错误:"Reducers may not dispatch actions."。Reducer 是纯函数——它们只能返回新的状态值,且不能有副作用(而派发 action 是副作用)。
在 Redux 中,订阅监听器在根 reducer 返回新状态后才会被调用,因此您可以在订阅监听器中派发 action。禁止在 reducer 内部派发的原因是其必须保持无副作用。若需在响应 action 时产生副作用,正确的做法是在可能是异步的 action 创建器 中处理。
参数
action(Object†):描述应用变更的普通对象。Action 是将数据存入 store 的唯一方式,因此来自 UI 事件、网络回调、WebSockets 或其他来源的任何数据最终都需要作为 action 派发。Action 必须包含type字段来指示操作类型。类型可定义为常量并从其他模块导入。type使用字符串而非 Symbols 更佳,因为字符串可序列化。除type外,action 对象的结构完全由您决定。如需参考,可查阅 Flux Standard Action 了解 action 的构造建议。
返回值
(Object†): The dispatched action (see notes).
注意事项
† The “vanilla” store implementation you get by calling createStore only supports plain object actions and hands them immediately to the reducer.
然而,若使用 applyMiddleware 包装 createStore,中间件可以不同方式解析 action,并提供对派发 异步 action 的支持。异步 action 通常是 Promise、Observable 或 thunk 等异步原语。
中间件由社区创建,默认不随 Redux 提供。您需要显式安装 redux-thunk 或 redux-promise 等包才能使用。您也可以创建自己的中间件。
要了解如何描述异步 API 调用、在 action 创建器中读取当前状态、执行副作用或按顺序链式执行,请参阅 applyMiddleware 的示例。
示例
import { createStore } from 'redux'
const store = createStore(todos, ['Use Redux'])
function addTodo(text) {
return {
type: 'ADD_TODO',
text
}
}
store.dispatch(addTodo('Read the docs'))
store.dispatch(addTodo('Read about the middleware'))
subscribe(listener)
添加变更监听器。每当 action 被分发且状态树可能发生变化时,该监听器将被调用。您可以在回调函数中调用 getState() 来读取当前状态树。
您可以从变更监听器中调用 dispatch(),但需注意以下限制:
-
监听器应仅在响应用户操作或特定条件下调用
dispatch()(例如当 store 包含特定字段时分发 action)。无条件调用dispatch()技术上可行,但通常会导致无限循环,因为每次dispatch()调用都会再次触发监听器。 -
订阅列表会在每次
dispatch()调用前生成快照。若在监听器执行期间订阅或取消订阅,不会影响当前正在进行的dispatch()。但下一次dispatch()调用(无论是否嵌套)将使用更新的订阅列表快照。 -
监听器不应期望看到所有状态变更,因为在嵌套
dispatch()过程中状态可能已更新多次,而监听器仅在最后被调用。但可以保证:所有在dispatch()开始前注册的订阅者,都会在其结束时以最新状态被调用。
这是底层 API。通常您会使用 React(或其他)绑定库而非直接调用。若需通过回调响应状态变更,建议编写自定义的 observeStore 工具。Store 也是Observable,因此可通过 RxJS 等库使用 subscribe 方法订阅变更。
要取消变更监听,请调用 subscribe 返回的函数。
参数
listener(Function): 每当 action 被分发且状态树可能变更时触发的回调函数。您可在回调内调用getState()读取当前状态树。由于 store 的 reducer 是纯函数,可通过比较状态树深层路径的引用来判断值是否变更。
返回值
(Function): 用于取消变更监听的函数。
示例
function select(state) {
return state.some.deep.property
}
let currentValue
function handleChange() {
let previousValue = currentValue
currentValue = select(store.getState())
if (previousValue !== currentValue) {
console.log(
'Some deep nested property changed from',
previousValue,
'to',
currentValue
)
}
}
const unsubscribe = store.subscribe(handleChange)
unsubscribe()
replaceReducer(nextReducer)
替换 store 当前用于计算状态的 reducer。
这是高级 API。当应用实现代码分割需动态加载部分 reducer,或为 Redux 实现热重载机制时可能需要使用。
参数
nextReducer(Function) store 将使用的新 reducer。