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

React useEffect中cart过滤结果无法存入useState导致状态不一致如何解决

问题原因
  • 执行时序错误:你当前的代码执行顺序是:组件挂载后触发useEffect,先执行setArticle(cart.filter((e) => e.id === id)),此时cart还是初始值[],筛选结果必然是空;之后才调用异步的fetchCartAndPrice请求接口,等接口返回调用setCart更新购物车状态时,useEffect因为是空依赖不会再次执行,article也就不会再更新。
  • 状态更新的快照特性:React的状态更新是异步的,就算你把setArticle放到fetchCartAndPrice内部的setCart后面,本次渲染周期里拿到的cart还是旧值,也没法立刻筛选出正确的结果。
  • 方法使用不符合预期:Array.filter返回的是符合条件的所有元素组成的数组,如果你只需要匹配id的单个商品,应该用Array.find,返回的是匹配到的单个元素,找不到则为undefined,更符合article的语义。
修复方案

拆分逻辑,把请求购物车和筛选article的逻辑分开,把需要响应变化的筛选逻辑放到单独的useEffect中,补充正确的依赖项:

const [article, setArticle] = useState();
const [cart, setCart] = useState([]);
const { id } = useParams();

// 只负责请求购物车数据,挂载时执行一次
useEffect(() => {
  const fetchCartAndPrice = async () => {
    const { sess } = await ApiClientShoppingCart.getCart();
    setCart(sess.cart);
  };
  fetchCartAndPrice();
}, []);

// cart或id变化时自动筛选对应的article
useEffect(() => {
  setArticle(cart.find((e) => e.id === id));
}, [cart, id]);

return (
  <div>
    {console.log(cart.filter((e) => e.id === id))}
    {console.log(article)}
  </div>
);
}

如果article没有其他需要手动更新的场景,也可以直接去掉对应的状态,在渲染层直接计算更简洁:

const [cart, setCart] = useState([]);
const { id } = useParams();
// 直接计算,cart或id变化时会自动更新
const article = cart.find(e => e.id === id);

useEffect(() => {
  const fetchCartAndPrice = async () => {
    const { sess } = await ApiClientShoppingCart.getCart();
    setCart(sess.cart);
  };
  fetchCartAndPrice();
}, []);

return (
  <div>
    {console.log(cart.filter((e) => e.id === id))}
    {console.log(article)}
  </div>
);
}

内容的提问来源于stack exchange,提问作者C.G.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:36:03