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
相关产品推荐
相关产品推荐

