You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中useState在useEffect内统计订单状态计数异常问题

解决订单状态计数更新错误问题

模拟订单数据

const mockOrders = [
  { id: 1, status: "Completed" },
  { id: 2, status: "Completed" },
  { id: 3, status: "Completed" },
  { id: 4, status: "Pending" },
  { id: 5, status: "Cancelled" }
];

错误代码分析

你的问题出在闭包导致的状态依赖错误,典型错误写法如下:

import { useState, useEffect } from 'react';

function OrderStats() {
  const [counts, setCounts] = useState({
    Completed: 0,
    Pending: 0,
    Cancelled: 0
  });

  useEffect(() => {
    mockOrders.forEach(order => {
      // 错误点:useEffect依赖为空数组,counts始终是初始化时的对象
      setCounts({
        ...counts,
        [order.status]: counts[order.status] + 1
      });
    });
  }, []);

  return (
    <div>
      <p>Completed: {counts.Completed}</p>
      <p>Pending: {counts.Pending}</p>
      <p>Cancelled: {counts.Cancelled}</p>
    </div>
  );
}

每次调用setCounts时,counts都是组件初始化的初始值,所以每个状态的计数只会被加1一次,最终所有有订单的状态都显示1。

正确解决方案

方案1:使用函数式更新

利用setState的函数形式,每次更新都基于最新的状态值:

useEffect(() => {
  mockOrders.forEach(order => {
    setCounts(prevCounts => ({
      ...prevCounts,
      [order.status]: prevCounts[order.status] + 1
    }));
  });
}, []);

方案2:预先计算完整计数再更新

一次性计算所有状态的总数,只调用一次setCounts,性能更优:

useEffect(() => {
  const statusCounts = mockOrders.reduce((acc, order) => {
    acc[order.status] += 1;
    return acc;
  }, { Completed: 0, Pending: 0, Cancelled: 0 });
  
  setCounts(statusCounts);
}, []);

这两种写法都能正确统计各类状态的订单数量,比如3个Completed、1个Pending、1个Cancelled。

内容的提问来源于stack exchange,提问作者Priyom saha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 19:27:06