使用 useEffect、useState 和 useSWR 创建无限循环

huangapple go评论70阅读模式
英文:

Infinite loop using useEffect, useState and useSWR

问题

const [useStateVar, setUseStateVar] = useState({});
const { data } = useSWR("demo/data", fetcher, { refreshInterval: 1000 });

useEffect(() => {
  // Ensure data exists before updating state
  if (data !== undefined) {
    setUseStateVar((prevState) => {
      // Update the state based on the previous state
      return { ...prevState, newData: data };
    });
  }
}, [data]);
英文:
const [ useStateVar, setUseStateVar ] = useState({})
const { data } = useSWR("demo/data", fetcher, {refreshInterval: 1000})

useEffect(() => {setUseStateVar(useStatevar+1)}, [data])

I believe the above code runs like this:
When the data first update at a 1s frequent, it triggers the useEffect() to update useStateVar using setUseStateVar, once the useStatevar is updated, the data update again, when the data updated, it triggers the useEffect(), so it created an infinite loop to the browser to update the value and hit the maximum.

I aim to get the updated data using useSWR() and update some variables, and reload the component while data is updated.

How can I achieve it without creating an infinite loop?

答案1

得分: 1

为了防止你的代码中出现无限循环,你可以使用 useRef 钩子来跟踪由 useSWR 获取的数据的先前值。这样,你可以将当前数据与先前值进行比较,并在数据发生变化时有条件地更新 useStateVar。以下是如何实现的代码示例:

import { useState, useEffect, useRef } from 'react';
import useSWR from 'swr';

const Component = () => {
  const [useStateVar, setUseStateVar] = useState({});
  const { data } = useSWR("demo/data", fetcher, { refreshInterval: 1000 });

  // 创建一个 ref 以跟踪先前的数据值
  const prevDataRef = useRef();

  useEffect(() => {
    // 检查 prevDataRef.current 是否存在并且数据是否发生了变化
    if (prevDataRef.current && data !== prevDataRef.current) {
      // 仅在数据发生变化时更新 useStateVar
      setUseStateVar(prevState => {
        // 根据新数据修改状态
        // 例如,你可以将新数据与先前状态合并
        return { ...prevState, ...data };
      });
    }

    // 使用当前数据值更新 prevDataRef 以供下一次比较
    prevDataRef.current = data;
  }, [data]);

  // 组件其余代码
  return (
    // JSX 元素
  );
}

useRef 钩子用于创建 prevDataRef,它保存了先前的数据值。在 useEffect 钩子内部,我们检查 prevDataRef.current 是否存在(即不为 null 或 undefined),以及当前数据值是否与先前的数据值不同。

如果数据发生变化,我们通过将新数据与先前状态合并(你可以根据具体的用例修改此部分)来更新 useStateVar 状态。

通过比较当前数据和先前数据的值,我们确保只有在 useSWR 获取的数据真正发生变化时才会更新 useStateVar 状态,从而避免了无限循环问题。

英文:

To prevent the infinite loop in your code, you can use the useRef hook to keep track of the previous value of the data fetched by useSWR. This way, you can compare the current data with the previous value and conditionally update the useStateVar only when the data changes. Here's how you can achieve it:

import { useState, useEffect, useRef } from 'react';
import useSWR from 'swr';

const Component = () => {
  const [useStateVar, setUseStateVar] = useState({});
  const { data } = useSWR("demo/data", fetcher, { refreshInterval: 1000 });

  // Create a ref to keep track of the previous data value
  const prevDataRef = useRef();

  useEffect(() => {
    // Check if prevDataRef.current exists and if the data has changed
    if (prevDataRef.current && data !== prevDataRef.current) {
      // Update the useStateVar only when the data changes
      setUseStateVar(prevState => {
        // Modify the state based on the new data
        // For example, you can merge the new data with the previous state
        return { ...prevState, ...data };
      });
    }

    // Update the prevDataRef with the current data value for the next comparison
    prevDataRef.current = data;
  }, [data]);

  // Rest of your component code
  return (
    // JSX elements
  );
}

the useRef hook is to create prevDataRef, which holds the previous value of data. Inside the useEffect hook, we check if the prevDataRef.current exists (i.e., it is not null or undefined) and if the current data value is different from the previous one.

If there's a change in the data, we update the useStateVar state by merging the new data with the previous state (you can modify this part based on your specific use case).

comparing the current and previous data values, we ensure that the useStateVar state is only updated when there's a genuine change in the data fetched by useSWR, avoiding the infinite loop issue.

huangapple
  • 本文由 发表于 2023年7月27日 18:55:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76779046.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定