Loading... ### React useReducer 状态管理高级指南 > 🚀 `useReducer` 是 React 中处理复杂状态逻辑的核武器。本文将揭示 2024 年最新高级技巧,涵盖**异步操作**、**状态机**、**性能优化**等深度应用场景。 --- ### 🧠 核心原理图解 ```mermaid graph TD A[Action] --> B(reducer) B --> C{状态更新} C --> D[新状态] C --> E[副作用] E --> F(useEffect) D --> G[UI渲染] ``` --- ### 🔧 七大高级技巧实战 #### 1. 异步操作处理(支持Suspense) ```jsx // 异步reducer模板 function asyncReducer(state, action) { switch (action.type) { case 'FETCH_START': return { ...state, loading: true, error: null }; case 'FETCH_SUCCESS': return { data: action.payload, loading: false, error: null }; case 'FETCH_ERROR': return { ...state, loading: false, error: action.error }; default: return state; } } // 组件中使用 const fetchData = async () => { dispatch({ type: 'FETCH_START' }); try { const res = await fetch('/api/data'); const data = await res.json(); dispatch({ type: 'FETCH_SUCCESS', payload: data }); } catch (error) { dispatch({ type: 'FETCH_ERROR', error }); } }; ``` **优化点**: * 使用 `AbortController` 取消未完成请求 * 结合 `React.Suspense` 实现加载状态 #### 2. 状态机集成(XState模式) ```jsx // 有限状态机配置 const machineConfig = { initial: 'idle', states: { idle: { on: { START: 'loading' } }, loading: { on: { SUCCESS: 'success', FAIL: 'error' }, effect: () => fetchData() }, success: { on: { RESET: 'idle' } }, error: { on: { RETRY: 'loading' } } } }; // reducer实现状态机 function stateMachineReducer(state, action) { const nextState = machineConfig.states[state.status].on[action.type]; return nextState ? { ...state, status: nextState } : state; } // 初始化 const [state, dispatch] = useReducer(stateMachineReducer, { status: 'idle', data: null }); ``` #### 3. 不可变更新优化(Immer集成) ```jsx import produce from 'immer'; function reducer(state, action) { return produce(state, draft => { switch (action.type) { case 'ADD_ITEM': draft.items.push(action.item); // 直接修改draft break; case 'UPDATE_USER': draft.users[action.id] = action.user; break; } }); } ``` **性能优势**: * 避免深拷贝开销 * 保持不可变性原则 #### 4. 状态持久化(localStorage同步) ```jsx const PERSIST_KEY = 'app_state'; function init(initialState) { // 从localStorage恢复状态 const savedState = localStorage.getItem(PERSIST_KEY); return savedState ? JSON.parse(savedState) : initialState; } function reducer(state, action) { const newState = /* 状态计算逻辑 */; // 每次更新后保存 localStorage.setItem(PERSIST_KEY, JSON.stringify(newState)); return newState; } // 使用 const [state, dispatch] = useReducer(reducer, initialState, init); ``` #### 5. 跨组件状态共享(Context + useReducer) ```jsx // 创建Context const StateContext = React.createContext(); function App() { const [state, dispatch] = useReducer(reducer, initialState); return ( <StateContext.Provider value={{ state, dispatch }}> <ChildComponent /> </StateContext.Provider> ); } // 子组件中使用 function Child() { const { dispatch } = useContext(StateContext); const handleClick = () => { dispatch({ type: 'INCREMENT' }); }; } ``` #### 6. 撤销/重做功能实现 ```jsx function historyReducer(state, action) { switch (action.type) { case 'UNDO': return { past: state.past.slice(0, -1), present: state.past[state.past.length - 1], future: [state.present, ...state.future] }; case 'REDO': return { past: [...state.past, state.present], present: state.future[0], future: state.future.slice(1) }; default: // 普通操作 return { past: [...state.past, state.present], present: reducer(state.present, action), future: [] }; } } // 初始化 const [state, dispatch] = useReducer(historyReducer, { past: [], present: initialState, future: [] }); ``` #### 7. 性能优化(useMemo + 选择性更新) ```jsx // 创建稳定dispatch const stableDispatch = useCallback(dispatch, []); // 避免子组件无效渲染 const contextValue = useMemo(() => ({ state: { user: state.user, // 仅暴露必要状态 settings: state.settings }, dispatch: stableDispatch }), [state.user, state.settings, stableDispatch]); ``` --- ### 📊 useReducer vs useState 场景对比 | **场景** | **useReducer** | **useState** | | -------------- | -------------------- | ------------------ | | 状态复杂度 | ✅ 多字段关联状态 | ❌ 简单状态 | | 更新逻辑 | ✅ 复杂业务逻辑 | ❌ 直接赋值 | | 性能优化 | ✅ 精确更新 | ❌ 全量更新 | | 异步处理 | ✅ 内置状态机 | ❌ 需额外逻辑 | | 状态共享 | ✅ Context集成 | ❌ 需状态提升 | | 历史记录 | ✅ 内置历史栈 | ❌ 需自定义 | --- ### ⚙️ 高级模式模板 #### 1. 中间件系统(Redux风格) ```jsx const useReducerWithMiddleware = (reducer, initialState, middlewares) => { const [state, dispatch] = useReducer(reducer, initialState); const enhancedDispatch = useCallback(action => { // 中间件执行链 const chain = middlewares.map(mw => mw({ getState: () => state })); const enhanced = compose(...chain)(dispatch); enhanced(action); }, [state, middlewares]); return [state, enhancedDispatch]; }; // 日志中间件示例 const logger = ({ getState }) => next => action => { console.log('Dispatching:', action); const result = next(action); console.log('New state:', getState()); return result; }; ``` #### 2. 状态分片(大型应用架构) ```jsx // 分片reducer组合 const rootReducer = combineReducers({ user: userReducer, cart: cartReducer, products: productsReducer }); function combineReducers(reducers) { return (state = {}, action) => { const nextState = {}; Object.keys(reducers).forEach(key => { nextState[key] = reducers[key](state[key], action); }); return nextState; }; } // 使用 const [state, dispatch] = useReducer(rootReducer, { user: null, cart: [], products: [] }); ``` --- ### ⚠️ 三大性能陷阱及解决方案 #### 1. 无效渲染问题 ```jsx // 错误:直接传递整个状态 <Context.Provider value={{ state, dispatch }}> // 正确:选择必要状态 <Context.Provider value={useMemo(() => ({ user: state.user, dispatch }), [state.user])}> ``` #### 2. 函数重复创建 ```jsx // 错误:每次渲染创建新函数 const addItem = item => dispatch({ type: 'ADD', item }); // 正确:useCallback缓存 const addItem = useCallback( item => dispatch({ type: 'ADD', item }), [dispatch] ); ``` #### 3. 大型状态树更新 ```jsx // 错误:更新整个大对象 dispatch({ type: 'UPDATE', payload: hugeObject }); // 正确:局部更新 dispatch({ type: 'UPDATE_SECTION', section: 'profile', data: newData }); ``` --- ### 💡 最佳实践原则 1. **状态结构化**: ```jsx // 扁平化状态结构state = { users: { byId: { 1: {...}, 2: {...} }, allIds: [1, 2] }} ``` 2. **操作标准化**: ```jsx // 使用Flux Standard Action{ type: 'USER_ADD', payload: userData, meta: { timestamp: Date.now() }} ``` 3. **副作用隔离**: ```jsx useEffect(() => { if (state.needsFetch) { fetchData(); }}, [state.needsFetch]); ``` > 🔥 **黄金法则**: > > * 复杂状态用 `useReducer` > * 关联操作放 `reducer` > * 异步逻辑入 `useEffect` > * 性能优化靠 `useMemo` 掌握这些技巧,可构建高性能、可维护的 React 应用,适用于 React 18+ 最新特性。 最后修改:2025 年 08 月 08 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏