简体   繁体   English

useEffect 导致无限循环

[英]useEffect causing infinite loop

I have looked at every infinite loop answer in SO and I cannot figure out what I'm doing wrong.我查看了 SO 中的每个无限循环答案,但我无法弄清楚我做错了什么。

I'm trying to fetch some data and set my productList state with the data but it causes an infinite loop.我正在尝试获取一些数据并使用数据设置我的 productList state ,但这会导致无限循环。

export default (props) => {
  const [productsList, setProductsList] = useState([]);

  const getProducts = async () => {
    try {
      await axios
        .get("https://api.stripe.com/v1/skus", {
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${StripeKey}`,
          },
        })
        .then(({ data }) => {
          setProductsList(data.data);
        });
    } catch {
      (error) => {
        console.log(error);
      };
    }
  };

  useEffect(() => {
    getProducts();
  }, [productList]);

  return (
    <ProductsContext.Provider value={{ products: productsList }}>
      {props.children}
    </ProductsContext.Provider>
  );
};

I have also tried with having an empty array at the end of useEffect and that causes it to not set the state at all.我也尝试过在 useEffect 末尾有一个空数组,这导致它根本不设置 state。

What am I missing?我错过了什么?

EDIT:编辑:

I removed the try/catch and [productList] from useEffect我从 useEffect 中删除了 try/catch 和 [productList]

import React, { useState, useEffect } from "react";
import axios from "axios";

const StripeKey = "TEST_KEY";

export const ProductsContext = React.createContext({ products: [] });

export default (props) => {
  const [productsList, setProductsList] = useState([]);

  useEffect(() => {
    axios({
      method: "get",
      url: "https://api.stripe.com/v1/skus",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${StripeKey}`,
      },
    })
      .then((response) => {
        setProductsList(response.data.data)
      })
      .catch((error) => {
        console.log(error);
      });
  }, []);

  return (
    <ProductsContext.Provider value={{ products: productsList }}>
      {props.children}
    </ProductsContext.Provider>
  );
};

About how you fetch your data: I think the problem might be on how you are fetching data:关于如何获取数据:我认为问题可能在于您如何获取数据:

As stated in docs I think you should not be using try catch here, but something like:文档中所述,我认为您不应该在这里使用 try catch,而是使用类似:

function MyComponent() {
  const [error, setError] = useState(null);
  const [isLoaded, setIsLoaded] = useState(false);
  const [items, setItems] = useState([]);

  // Note: the empty deps array [] means
  // this useEffect will run once
  // similar to componentDidMount()
  useEffect(() => {
    fetch("https://api.example.com/items")
      .then(res => res.json())
      .then(
        (result) => {
          setIsLoaded(true);
          setItems(result.items);
        },
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
          setIsLoaded(true);
          setError(error);
        }
      )
  }, [])

  if (error) {
    return <div>Error: {error.message}</div>;
  } else if (!isLoaded) {
    return <div>Loading...</div>;
  } else {
    return (
      <ul>
        {items.map(item => (
          <li key={item.name}>
            {item.name} {item.price}
          </li>
        ))}
      </ul>
    );
  }
}

About the useEffect callback:关于 useEffect 回调:

I don't think you should use [productList] as its the item you are updating, so it would trigger again once you do the setProducts.我认为您不应该使用 [productList] 作为您要更新的项目,因此一旦您执行 setProducts,它将再次触发。 You might want to do the fetching again when a prop of the request changes or just on component did mount (empty array as you said)当请求的道具更改或仅在组件上安装时,您可能希望再次进行获取(如您所说的空数组)

Also, there might be other side effects we cannot see with that sample of code.此外,该代码示例可能还有其他我们看不到的副作用。 Maybe you could share an stackblitz to be sure也许你可以分享一个stackblitz来确定

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM