Store:Redux 的核心,存储了整个应用程序的状态树。应用中的所有状态都存储在一个 Store 中,这使得状态管理变得更加集中和一致。
Action:描述状态变化的对象。每个 Action 都是一个包含 type
属性的纯对象,type
是字符串常量,用于描述这次操作的类型。Action 还可以包含额外的状态信息。
Reducer:一个纯函数,接收当前的 state 和 action,返回新的 state。Reducer 是唯一可以修改状态的地方,通过处理 Action 来生成新的状态。
Dispatch:发送 Action 到 Store。通过 dispatch
,可以触发 Reducer 执行,从而更新 Store 中的状态。
State:应用程序的当前状态树,是由 Reducer 返回的状态对象。
Middleware:中间件是在 dispatch
Action 和到达 Reducer 之间的扩展点,常用于处理异步操作、日志记录等。
Redux 的工作原理可以通过以下几个步骤理解:
初始状态:
combineReducers
将它们合并。import { createStore } from 'redux';
// 一个简单的 reducer,初始化 state 并返回 state
function counterReducer(state = { count: 0 }, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
}
// 创建 store,传入 reducer
const store = createStore(counterReducer);
分发 Action:
dispatch
方法发送一个 Action。// 创建 action
const incrementAction = { type: 'INCREMENT' };
// 分发 action
store.dispatch(incrementAction);
Reducer 更新状态:
function counterReducer(state = { count: 0 }, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
}
State 更新和 UI 渲染:
store.subscribe(() => {
console.log(store.getState());
});
store.dispatch({ type: 'INCREMENT' }); // 输出: { count: 1 }
单一状态树:整个应用的状态被存储在一个对象树中,而这个对象树只存在于唯一的一个 Store 中。这样可以使应用程序的状态管理变得更加集中和可控。
状态只读:应用的状态是只读的,无法直接修改。唯一改变状态的方式就是触发 Action,这保证了数据流的可预测性。
纯函数的 Reducer:Reducer 是纯函数,不依赖于外部变量,只通过传入的参数(state 和 action)来决定返回值。这使得 Redux 应用中的状态变化更加透明和可测试。
Redux 本身是同步的,但在实际开发中,我们经常需要处理异步操作,如数据请求。Redux 提供了中间件机制,常用的异步处理中间件有 redux-thunk
和 redux-saga
。
redux-thunk:允许 Action Creators 返回函数,而不是普通对象。这个函数可以包含异步逻辑,比如发送请求,并在异步操作完成后 dispatch
其他 Action。
// redux-thunk 异步 action 示例
function fetchData() {
return function(dispatch) {
// 异步操作开始
dispatch({ type: 'FETCH_START' });
// 异步请求
fetch('/api/data')
.then(response => response.json())
.then(data => {
// 异步操作完成,分发成功 action
dispatch({ type: 'FETCH_SUCCESS', payload: data });
})
.catch(error => {
// 异步操作失败,分发失败 action
dispatch({ type: 'FETCH_FAILURE', error });
});
};
}
redux-saga:使用 generator 函数来处理副作用,具有更强的可读性和复杂场景的处理能力。
虽然 Redux 提供了强大的状态管理能力,但它也带来了一些挑战:
Redux 通过单一状态树、严格的单向数据流和纯函数的 Reducer,为 JavaScript 应用提供了可预测和可控的状态管理方式。它适用于大型应用程序,尤其是在需要多个组件共享和协作的状态时。然而,Redux 的使用需要在项目复杂性与开发成本之间权衡,选择合适的工具和设计模式至关重要。