React useEffect 不会将参数提取到 React useState

React useEffect does not fetch paramter into React useState

为什么我的文章状态没有与我的 cart.filter 元素相同的参数。 我做错了什么,使用 useState Hook。

  const [article, setArticle] = useState();
  const [cart, setCart] = useState([]);
  const { id } = useParams();
  useEffect(() => {
    const fetchCartAndPrice = async () => {
      const { sess } = await ApiClientShoppingCart.getCart();
      setCart(sess.cart);
    };
    setArticle(cart.filter((e) => e.id === id));
    fetchCartAndPrice();
  }, []);
  return (
    <div>
      {console.log(cart.filter((e) => e.id === id))}
      {console.log(article)}
    </div>
  );
}

当你触发你的函数时setArticle()获取购物车的异步函数还没有完成......所以它不能“过滤”(仍然是空的)购物车......

您需要在设置购物车后执行该过滤器:

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

useEffect(() => {
  // --> ensure we are not in the "init step"
  if (cart.length) {
    setArticle(cart.filter((e) => e.id === id));

    // Not sur where this one belongs ... :
    fetchCartAndPrice();
  }
}, [cart]);

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

另一种方法是将商品放在购物车的同一位置:

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

在您尝试设置的那一刻,文章还没有购物车。您需要等待购物车更新创建一个独占的 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();
}, []);

useEffect(() => {
  setArticle(cart.filter((e) => e.id === id));
}, [cart]);

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

Gabriel Furlan 给出了一个很好的解决方案。 我会在 useEffect 挂钩的顶层使用异步声明。 例如

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

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

useEffect(() => {
  setArticle(cart.filter((e) => e.id === id));
}, [cart]);

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