React:无法在addToBasket函数中访问order状态数组的解决方案求助
React useState 状态更新时无法在函数内获取最新值的解决方案
我需要有条件地更新数组order的状态(检查重复项),但无法在addToBasket函数内部访问到order的最新值;不过组件顶层的console.log(order)却能正常打印更新后的order。代码片段如下:
const [order, setOrder] = useState<IGoodsCart[]>([]); console.log(order); // 1 能打印最新值 const addToBasket: AddToBasketFunc = (item) => { console.log(order); // 2 无法获取最新值 const itemIndex = order.findIndex((orderItem) => orderItem.id === item.id); if (itemIndex < 0) { const newItem = { ...item, quantity: 1, }; setOrder((order) => [...order, newItem]); } else { const newOrder = order.map((orderItem, index) => { if (index === itemIndex) { return { ...orderItem, quantity: orderItem.quantity + 1, }; } else { return orderItem; } }); setOrder(newOrder); } };
最佳处理方式:统一使用函数式更新
核心问题是闭包捕获旧状态:组件渲染时addToBasket会捕获当前周期的order值,状态更新后组件重新渲染才会生成新的addToBasket,旧函数里的order始终是之前的旧值。而函数式更新会接收React维护的最新状态作为参数,完全规避闭包问题。
修改后的完整代码:
const [order, setOrder] = useState<IGoodsCart[]>([]); console.log(order); // 正常打印最新值 const addToBasket: AddToBasketFunc = (item) => { setOrder((currentOrder) => { // 这里的currentOrder是实时最新的状态值 const itemIndex = currentOrder.findIndex(orderItem => orderItem.id === item.id); if (itemIndex < 0) { return [...currentOrder, { ...item, quantity: 1 }]; } else { return currentOrder.map((orderItem, index) => { if (index === itemIndex) { return { ...orderItem, quantity: orderItem.quantity + 1 }; } return orderItem; }); } }); };
为什么不推荐useRef?
useRef确实可以保存最新的状态值,但属于额外的状态维护逻辑,不符合React官方推荐的状态更新范式。函数式更新是专门为依赖最新状态的场景设计的,代码更简洁、更贴合React的状态管理逻辑,不需要额外维护ref变量。
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

