【问题标题】:React useEffect does not fetch paramter into React useStateReact useEffect 不会将参数获取到 React useState
【发布时间】:2021-11-17 20:09:32
【问题描述】:

为什么我的文章状态没有像我的 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>
  );
}

【问题讨论】:

    标签: reactjs react-hooks rerender


    【解决方案1】:

    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>
    );
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        当您触发函数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 之后的 setState 未定义......我不明白我做错了什么
        猜你喜欢
        • 2022-01-12
        • 1970-01-01
        • 1970-01-01
        • 2022-07-19
        • 1970-01-01
        • 2020-03-23
        • 1970-01-01
        • 2020-02-21
        • 1970-01-01
        相关资源
        最近更新 更多