【问题标题】:React- Issue with infinite loop in useEffectReact-useEffect中的无限循环问题
【发布时间】:2021-12-06 22:36:17
【问题描述】:

我有一个通过 axios 获取数据的 useEffect(),我希望它只渲染一次,所以我传递了一个数组。一切正常,但问题是每当我尝试对项目进行排序时,第二个 useEffect 会触发,然后是第一个 useEffect,这会导致组件一次又一次地获取项目。

const [products, setProducts] = useState([]);

useEffect(() => {
    const getProducts = async () => {
      return await axios
        .get('/getAllProducts')
        .then((response) => {
          setProducts(response.data);
          console.log(products);
        })
        .catch((e) => {
          console.log(e);
        });
    };
    getProducts();
  }, [products]);

【问题讨论】:

    标签: reactjs axios


    【解决方案1】:

    这是因为您传递了一个包含 products 状态的数组,而不是一个空数组,它将在状态更改时触发 useEffect(特别针对 products 状态)。尝试将您的代码更改为空数组:

    useEffect(() => {
    const getProducts = async () => {
      return await axios
        .get('/getAllProducts')
        .then((response) => {
          setProducts(response.data);
          console.log(products);
        })
        .catch((e) => {
          console.log(e);
        });
      };
      getProducts();
      }, []);
    

    正如下面提到的@skyboyer,请注意状态不是以同步方式更新的。因此,console.log(products) 不会在 useEffect 运行时反映您的状态的准确值。

    可以使用多个useEffect 挂钩。如果您想在控制台中查看更新后的状态,或者使用它做一些其他工作,您可以添加另一个 useEffect 钩子并将您的状态传递到数组中:

    useEffect(() => {
        console.log(products);
    }, [products]);
    

    【讨论】:

    • ...并删除 console.log(products) 以满足 ESlint 以及不输出 products 的先前值,这没有任何意义
    • 我认为它希望在从 axios 进行调用后查看产品状态的结果数据,因此它应该创建一个与调用分开的新 useEffect 以查看数据更改.. useEffect(() => { console.log(products); }, [products]);
    【解决方案2】:

    由于products 位于useEffect 依赖数组中,因此每次products 状态发生更改时都会运行它。 getProducts() 运行 setProducts 然后又会再次触发使用效果。在useEffect 中使用空数组将告诉它仅在组件安装时运行。

    像这样:

    useEffect(() => {
    const getProducts = async () => {
      return await axios
        .get('/getAllProducts')
        .then((response) => {
          setProducts(response.data);
          console.log(products);
        })
        .catch((e) => {
          console.log(e);
        });
      };
      getProducts();
      }, []);
    

    【讨论】:

    • 除了之前发布的答案之外,您的答案对主题有何贡献?
    猜你喜欢
    • 2021-01-31
    • 2020-04-14
    • 2020-09-06
    • 2019-08-15
    • 2021-10-21
    • 2021-11-01
    • 2020-02-21
    • 2020-07-24
    相关资源
    最近更新 更多