状态管理是指在React应用中存储、组织和更新数据的方式。良好的状态管理应确保数据流清晰、组件通信高效、调试方便。
useState, useReducer
Context API
Redux, Zustand等
React Query, SWR
JavaScript应用的可预测状态容器
小型、快速、可扩展的状态管理
简单、可扩展的状态管理
Facebook实验性状态管理
基于原子的状态管理
React内置状态共享
import { createStore } from 'redux';
// 初始状态
const initialState = {
count: 0,
user: null,
todos: []
};
// Reducer函数
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
case 'DECREMENT':
return { ...state, count: state.count - 1 };
case 'SET_USER':
return { ...state, user: action.payload };
case 'ADD_TODO':
return { ...state, todos: [...state.todos, action.payload] };
default:
return state;
}
};
// 创建Store
const store = createStore(rootReducer);
// Action创建函数
const increment = () => ({
type: 'INCREMENT'
});
const decrement = () => ({
type: 'DECREMENT'
});
const setUser = (user) => ({
type: 'SET_USER',
payload: user
});
const addTodo = (text) => ({
type: 'ADD_TODO',
payload: {
id: Date.now(),
text,
completed: false
}
});
import { Provider, useSelector, useDispatch } from 'react-redux';
// 提供Store给整个应用
function App() {
return (
<Provider store={store}>
<Counter />
<UserProfile />
</Provider>
);
}
// 在组件中使用
function Counter() {
const count = useSelector(state => state.count);
const dispatch = useDispatch();
return (
<div>
<p>计数: {count}</p>
<button onClick={() => dispatch(increment())}>增加</button>
<button onClick={() => dispatch(decrement())}>减少</button>
</div>
);
}
import { configureStore, createSlice } from '@reduxjs/toolkit';
// 创建Slice
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: state => {
state.value += 1;
},
decrement: state => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
}
}
});
// 导出Actions和Reducer
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
// 配置Store
const store = configureStore({
reducer: {
counter: counterSlice.reducer
}
});
import create from 'zustand';
// 创建Store
const useStore = create((set) => ({
// 状态
bears: 0,
fish: 0,
user: null,
// Actions
increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
removeAllBears: () => set({ bears: 0 }),
// 异步Action
fetchUser: async (userId) => {
const response = await fetch(`/api/users/${userId}`);
const user = await response.json();
set({ user });
},
// 复杂更新
updateUser: (updates) =>
set((state) => ({
user: { ...state.user, ...updates }
}))
}));
// 在组件中使用
function BearCounter() {
const bears = useStore((state) => state.bears);
const increasePopulation = useStore((state) => state.increasePopulation);
return (
<div>
<h1>熊的数量: {bears}</h1>
<button onClick={increasePopulation}>增加一只熊</button>
</div>
);
}
// 使用中间件
const useStoreWithMiddleware = create(
persist(
(set, get) => ({
todos: [],
addTodo: (text) =>
set({ todos: [...get().todos, { text, completed: false }] }),
}),
{
name: 'todo-storage', // localStorage key
}
)
);
总计: $0
商品数量: 0
| 需求 | 推荐方案 | 备选方案 |
|---|---|---|
| 快速原型/小型应用 | Context API | Zustand |
| 需要时间旅行调试 | Redux | MobX |
| 极简主义/讨厌样板代码 | Zustand | Jotai |
| 响应式/OOP风格 | MobX | Redux |
| Facebook生态/实验性 | Recoil | Context API |
整个应用的状态存储在一个对象树中,便于调试和跟踪
// Redux和Flux模式
const appState = {
user: {...},
cart: {...},
ui: {...}
};
状态被分解为最小的原子单位,可独立订阅和更新
// Recoil和Jotai
const countState = atom({
key: 'countState',
default: 0
});
状态变更自动反映到UI,UI操作自动更新状态
// MobX和Vuex
@observable count = 0;
@action increment() {
this.count++;
}
状态不能被修改,只能通过创建新状态来更新
// Redux和Immer
return {
...state,
count: state.count + 1
};
// 不好:存储冗余状态
const [todos, setTodos] = useState([]);
const [completedCount, setCompletedCount] = useState(0);
// 好:计算派生状态
const todos = useSelector(state => state.todos);
const completedCount = useMemo(() =>
todos.filter(todo => todo.completed).length,
[todos]
);
// 创建记忆化选择器
import { createSelector } from '@reduxjs/toolkit';
const selectTodos = state => state.todos;
export const selectCompletedTodos = createSelector(
[selectTodos],
todos => todos.filter(todo => todo.completed)
);
// 在组件中使用
const completedTodos = useSelector(selectCompletedTodos);
// 使用Redux Thunk
const fetchUser = (userId) => async (dispatch) => {
dispatch({ type: 'FETCH_USER_REQUEST' });
try {
const response = await api.getUser(userId);
dispatch({ type: 'FETCH_USER_SUCCESS', payload: response });
} catch (error) {
dispatch({ type: 'FETCH_USER_FAILURE', payload: error });
}
};
// 使用RTK Query
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
export const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
endpoints: (builder) => ({
getUser: builder.query({
query: (id) => `users/${id}`,
}),
}),
});
// 使用React Query
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
function UserList() {
const queryClient = useQueryClient();
// 查询数据
const { data: users, isLoading, error } = useQuery({
queryKey: ['users'],
queryFn: () => fetch('/api/users').then(res => res.json()),
staleTime: 5 * 60 * 1000, // 5分钟
});
// 创建数据
const createUser = useMutation({
mutationFn: (newUser) =>
fetch('/api/users', {
method: 'POST',
body: JSON.stringify(newUser),
}),
onSuccess: () => {
// 使users查询失效,触发重新获取
queryClient.invalidateQueries({ queryKey: ['users'] });
},
});
// 更新数据
const updateUser = useMutation({
mutationFn: ({ id, ...updates }) =>
fetch(`/api/users/${id}`, {
method: 'PUT',
body: JSON.stringify(updates),
}),
onMutate: async (newUser) => {
// 乐观更新
await queryClient.cancelQueries({ queryKey: ['users'] });
const previousUsers = queryClient.getQueryData(['users']);
queryClient.setQueryData(['users'], (old) =>
old.map(user => user.id === newUser.id ? newUser : user)
);
return { previousUsers };
},
onError: (err, newUser, context) => {
// 回滚乐观更新
queryClient.setQueryData(['users'], context.previousUsers);
},
});
if (isLoading) return 加载中...;
if (error) return 错误: {error.message};
return (
{users.map(user => (
{user.name}
))}
);
}
| 特性 | Redux | Zustand | MobX | Context API |
|---|---|---|---|---|
| 学习曲线 | 高 | 低 | 中 | 低 |
| 代码量 | 多 | 很少 | 中等 | 中等 |
| 性能 | 高 | 高 | 高 | 中等 |
| 调试工具 | 优秀 | 良好 | 良好 | 基础 |
| TypeScript支持 | 优秀 | 优秀 | 良好 | 良好 |
| 中间件支持 | 丰富 | 支持 | 支持 | 无 |
| 社区生态 | 极大 | 增长中 | 成熟 | React内置 |
| 适用场景 | 大型企业应用 | 中小型应用 | OOP风格应用 | 简单状态共享 |