首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >react useReducer 复杂状态管理

react useReducer 复杂状态管理

原创
作者头像
小焱
发布2025-08-16 09:04:58
发布2025-08-16 09:04:58
1070
举报
文章被收录于专栏:前端开发前端开发

useReducer 是 React 中用于管理复杂状态逻辑的 Hook,尤其适合处理具有多个子值的状态对象、存在复杂状态转换逻辑或多个操作影响同一状态的场景。它的工作方式类似 Redux 的 reducer 模式,通过 action 驱动状态更新,让状态变化逻辑更可预测、可维护。

核心概念

  • state:当前的状态值
  • action:一个描述“要做什么”的普通对象(通常包含 type 字段表示操作类型,以及其他必要数据)
  • reducer:一个纯函数,接收当前 stateaction,返回新的 state(state, action) => newState
  • dispatch:用于发送 action 的函数(调用 dispatch(action) 触发 reducer 执行)

基础用法

1. 定义 reducer 函数

reducer 是纯函数,根据 action.type 决定如何更新状态,不能直接修改原状态,必须返回新状态。

代码语言:jsx
复制
// 定义 reducer:根据 action 处理状态
function todoReducer(state, action) {
  switch (action.type) {
    case 'ADD_TODO':
      // 返回新数组(不修改原数组)
      return [
        ...state,
        { id: Date.now(), text: action.text, done: false }
      ];
    case 'TOGGLE_TODO':
      // 映射新数组,只修改目标项
      return state.map(todo =>
        todo.id === action.id ? { ...todo, done: !todo.done } : todo
      );
    case 'DELETE_TODO':
      // 过滤掉要删除的项
      return state.filter(todo => todo.id !== action.id);
    default:
      // 未知 action 时返回原状态
      return state;
  }
}
2. 在组件中使用 useReducer
代码语言:jsx
复制
import { useReducer } from 'react';

function TodoApp() {
  // 初始化状态(空数组),获取 [状态, dispatch函数]
  const [todos, dispatch] = useReducer(todoReducer, []);
  const [inputText, setInputText] = useState('');

  // 处理添加任务
  const handleAdd = () => {
    if (!inputText.trim()) return;
    // 发送 ADD_TODO 动作,携带必要数据
    dispatch({ type: 'ADD_TODO', text: inputText });
    setInputText(''); // 清空输入框
  };

  return (
    <div>
      <input
        value={inputText}
        onChange={(e) => setInputText(e.target.value)}
        placeholder="输入任务..."
      />
      <button onClick={handleAdd}>添加</button>
      
      <ul>
        {todos.map(todo => (
          <li
            key={todo.id}
            style={{ textDecoration: todo.done ? 'line-through' : 'none' }}
            onClick={() => dispatch({ type: 'TOGGLE_TODO', id: todo.id })}
          >
            {todo.text}
            <button onClick={() => dispatch({ type: 'DELETE_TODO', id: todo.id })}>
              删除
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

复杂场景优势

当状态逻辑复杂时(例如多字段联动、条件判断多、状态依赖前一个状态),useReduceruseState 更清晰:

示例:购物车状态管理
代码语言:jsx
复制
// 初始状态
const initialState = {
  items: [], // 商品列表
  total: 0,  // 总价
  count: 0   // 商品总数
};

// 复杂状态逻辑的 reducer
function cartReducer(state, action) {
  switch (action.type) {
    case 'ADD_ITEM': {
      const existingItem = state.items.find(item => item.id === action.item.id);
      let newItems;
      
      if (existingItem) {
        // 商品已存在,更新数量
        newItems = state.items.map(item =>
          item.id === action.item.id 
            ? { ...item, quantity: item.quantity + 1 } 
            : item
        );
      } else {
        // 新商品,添加到列表
        newItems = [...state.items, { ...action.item, quantity: 1 }];
      }
      
      // 计算新的总数和总价
      const count = newItems.reduce((sum, item) => sum + item.quantity, 0);
      const total = newItems.reduce((sum, item) => sum + (item.price * item.quantity), 0);
      
      return { ...state, items: newItems, count, total };
    }
    
    case 'REMOVE_ITEM': {
      // 实现删除商品逻辑...
    }
    
    default:
      return state;
  }
}

// 组件中使用
function ShoppingCart() {
  const [cart, dispatch] = useReducer(cartReducer, initialState);
  
  const addToCart = (product) => {
    dispatch({ type: 'ADD_ITEM', item: product });
  };
  
  // ...渲染购物车
}

useState 的对比

场景

推荐使用

原因

简单状态(单值)

useState

语法更简洁,无需定义 reducer

复杂状态(多字段/联动)

useReducer

状态逻辑集中在 reducer 中,便于调试和复用,避免多个 setState 嵌套

需要预测状态变化

useReducer

action 可追踪,方便回溯状态变更历史

注意事项

  1. reducer 必须是纯函数:不能修改原 state、不能执行副作用(如请求、定时器),仅根据输入计算输出。
  2. 状态更新是批量的:多次 dispatch 会合并处理,类似 setState
  3. 初始化状态:可直接传初始值,或通过函数返回(适合复杂初始化逻辑):// 函数式初始化(只执行一次) const [state, dispatch] = useReducer(reducer, null, () => { return { count: localStorage.getItem('count') || 0 }; });

通过 useReducer,可以将复杂状态逻辑从组件中抽离,让组件更专注于 UI 渲染,同时使状态变化更可预测、易于测试。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 核心概念
  • 基础用法
    • 1. 定义 reducer 函数
    • 2. 在组件中使用 useReducer
  • 复杂场景优势
    • 示例:购物车状态管理
  • 与 useState 的对比
  • 注意事项
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档