状态管理
本页面介绍如何使用 Redux Toolkit 的 createSlice 和 createEntityAdapter.
何时使用 Slice 与 RTK Query
为你的状态选择合适的工具:
状态类型
工具
示例
远程数据 (由服务器拥有)
RTK Query
用户资料、NFT、目录项、订单
UI 状态 (由客户端拥有)
createSlice
筛选器、模态框、视图偏好、表单状态
规范化集合
createEntityAdapter
已排序/已筛选列表、乐观更新
创建基础 Slice
将 createSlice 用于简单的 UI 状态:
// src/features/ui/ui.slice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import type { RootState } from '@/app/store';
interface UIState {
sidebarOpen: boolean;
modalOpen: boolean;
viewMode: 'grid' | 'list';
theme: 'light' | 'dark';
}
const initialState: UIState = {
sidebarOpen: true,
modalOpen: false,
viewMode: 'grid',
theme: 'light',
};
const uiSlice = createSlice({
name: 'ui',
initialState,
reducers: {
// 布尔切换
sidebarToggled(state) {
state.sidebarOpen = !state.sidebarOpen;
},
// 设置特定值
modalOpened(state) {
state.modalOpen = true;
},
modalClosed(state) {
state.modalOpen = false;
},
// Payload 动作
viewModeChanged(state, action: PayloadAction<'grid' | 'list'>) {
state.viewMode = action.payload;
},
themeChanged(state, action: PayloadAction<'light' | 'dark'>) {
state.theme = action.payload;
},
// 多个属性
uiReset() {
return initialState;
},
},
});
// 导出 actions
export const {
sidebarToggled,
modalOpened,
modalClosed,
viewModeChanged,
themeChanged,
uiReset,
} = uiSlice.actions;
// 导出 reducer
export default uiSlice.reducer;
// 导出选择器
export const selectSidebarOpen = (state: RootState) => state.ui.sidebarOpen;
export const selectModalOpen = (state: RootState) => state.ui.modalOpen;
export const selectViewMode = (state: RootState) => state.ui.viewMode;
export const selectTheme = (state: RootState) => state.ui.theme;使用 Entity Adapter
对于规范化集合(带 ID 的列表),使用 createEntityAdapter:
Entity Adapter 方法
状态修改
生成的选择器
复杂状态示例
在一个 slice 中组合多个关注点:
记忆化选择器
将 createSelector 来自 Reselect,用于计算/派生状态:
使用 extraReducers 的异步逻辑
在你的 slice 中处理 RTK Query 或 async thunk 的响应:
最佳实践
1. 保持状态最小化
2. 使用适合 Immer 的修改方式
3. 合理组织 Reducer
4. 正确为 Action 添加类型
测试 Slice
下一步
最后更新于