redux用法总结
目录
- 基本概念
- 工作原理
- 核心概念
- 基本使用
- 异步操作
- Redux Thunk
- Redux Saga
- React 集成
- Redux Toolkit
- 最佳实践
基本概念
什么是 Redux?
Redux 是一个可预测的状态容器,用于管理 JavaScript 应用的状态。它遵循三个基本原则:
- 单一数据源:整个应用的状态存储在单个 store 中
- 状态是只读的:唯一改变状态的方式是触发 action
- 使用纯函数进行修改:使用 reducer 来指定状态如何更新
核心概念图
Action --> Dispatcher --> Store --> View
^ |
| |
+--------------------------------+
工作原理
1. 基本流程
// 1. 创建 action
const addTodo = (text: string) => ({
type: 'ADD_TODO',
payload: text
});
// 2. Reducer 处理 action
const todoReducer = (state = [], action) => {
switch (action.type) {
case 'ADD_TODO':
return [...state, action.payload];
default:
return state;
}
};
// 3. 创建 store
const store = createStore(todoReducer);
// 4. 订阅变化
store.subscribe(() => {
console.log('State updated:', store.getState());
});
// 5. 发送 action
store.dispatch(addTodo('Learn Redux'));
核心概念
1. Action
// Action 类型定义
interface Action {
type: string;
payload?: any;
}
// Action Creator
const increment = (amount: number): Action => ({
type: 'INCREMENT',
payload: amount
});
2. Reducer
// 基本 reducer
const counterReducer = (state = 0, action: ActionType) => {
switch (action.type) {
case 'INCREMENT':
return state + action.payload;
case 'DECREMENT':
return state - action.payload;
default:
return state;
}
};
// 组合 reducers
const rootReducer = combineReducers({
counter: counterReducer,
todos: todosReducer
});
3. Store
// 创建 store
const store = createStore(rootReducer);
// 获取状态
console.log(store.getState());
// 订阅变化
const unsubscribe = store.subscribe(() => {
console.log('State updated:', store.getState());
});
// 发送 action
store.dispatch(increment(5));
异步操作
1. Redux Thunk
// actions/userActions.ts
import { Dispatch } from 'redux';
export const fetchUser = (id: string) => {
return async (dispatch: Dispatch) => {
dispatch({ type: 'FETCH_USER_REQUEST' });
try {
const response = await fetch(`/api/users/${id}`);
const data = await response.json();
dispatch({ type: 'FETCH_USER_SUCCESS', payload: data });
} catch (error) {
dispatch({ type: 'FETCH_USER_FAILURE', payload: error.message });
}
};
};
2. Redux Saga
2.1 基本概念
Redux Saga 是一个用于处理副作用的中间件,使用 ES6 的 Generator 函数。
2.2 核心 Effect Creators
take
: 等待指定 action 被触发put
: 触发一个新的 actioncall
: 调用异步函数fork
: 非阻塞调用select
: 获取 state 数据takeLatest
: 只执行最新的调用takeEvery
: 执行每一次调用all
: 并行执行race
: 竞态处理
2.3 基本配置
// 配置 Saga 中间件
import createSagaMiddleware from 'redux-saga';
import rootSaga from './sagas';
const sagaMiddleware = createSagaMiddleware();
const store = createStore(
rootReducer,
applyMiddleware(sagaMiddleware)
);
sagaMiddleware.run(rootSaga);
2.4 常见使用场景
- API 请求处理
function* fetchUserSaga(action) {
try {
const user = yield call(api.fetchUser, action.payload);
yield put({ type: 'FETCH_USER_SUCCESS', payload: user });
} catch (error) {
yield put({ type: 'FETCH_USER_FAILURE', error });
}
}
function* watchFetchUser() {
yield takeLatest('FETCH_USER_REQUEST', fetchUserSaga);
}
- 并发控制
function* fetchAll() {
const [users, posts] = yield all([
call(api.fetchUsers),
call(api.fetchPosts)
]);
yield put({ type: 'FETCH_ALL_SUCCESS', payload: { users, posts } });
}
- 轮询
function* pollData() {
while (true) {
try {
const data = yield call(api.fetchData);
yield put({ type: 'POLL_SUCCESS', payload: data });
yield delay(5000);
} catch (error) {
yield put({ type: 'POLL_FAILURE', error });
}
}
}
- 取消操作
function* fetchWithCancel() {
const bgTask = yield fork(backgroundTask);
yield take('CANCEL_FETCH');
yield cancel(bgTask);
}
2.5 适用场景
-
适合使用 Saga 的场景:
- 复杂的异步流程控制
- 需要取消的操作
- 并发控制
- API 调用序列
- 实时数据处理
- 复杂的状态同步
-
不适合使用 Saga 的场景:
- 简单的异步操作
- 同步操作
- 单一的 API 调用
React 集成
1. 使用 React-Redux
// App.tsx
import { Provider } from 'react-redux';
import store from './store';
function App() {
return (
<Provider store={store}>
<TodoList />
</Provider>
);
}
// components/TodoList.tsx
import { useSelector, useDispatch } from 'react-redux';
function TodoList() {
const todos = useSelector(state => state.todos);
const dispatch = useDispatch();
return (
// JSX
);
}
Redux Toolkit
1. 创建 Slice
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: state => {
state.value += 1;
},
decrement: state => {
state.value -= 1;
}
}
});
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
最佳实践
-
状态设计:
- 保持状态扁平化
- 避免冗余数据
- 使用规范化的数据结构
-
Action 设计:
- 使用动作创建器
- 保持 action 简单
- 使用类型常量
-
异步处理:
- 简单异步用 Thunk
- 复杂异步用 Saga
- 合理使用中间件
-
性能优化:
- 使用选择器模式
- 避免不必要的渲染
- 合理使用缓存
总结
-
Redux 优点:
- 可预测的状态管理
- 集中的状态管理
- 易于调试
- 强大的中间件生态
-
使用场景:
- 大型应用
- 复杂的状态逻辑
- 多人协作项目
- 需要状态持久化
-
最佳实践:
- 使用 TypeScript
- 采用 Redux Toolkit
- 实现状态范式化
- 使用选择器模式