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

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

Infinite loop using useEffect, useState and useSWR

问题

  1. const [useStateVar, setUseStateVar] = useState({});
  2. const { data } = useSWR("demo/data", fetcher, { refreshInterval: 1000 });
  3. useEffect(() => {
  4. // Ensure data exists before updating state
  5. if (data !== undefined) {
  6. setUseStateVar((prevState) => {
  7. // Update the state based on the previous state
  8. return { ...prevState, newData: data };
  9. });
  10. }
  11. }, [data]);
英文:
  1. const [ useStateVar, setUseStateVar ] = useState({})
  2. const { data } = useSWR("demo/data", fetcher, {refreshInterval: 1000})
  3. 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。以下是如何实现的代码示例:

  1. import { useState, useEffect, useRef } from 'react';
  2. import useSWR from 'swr';
  3. const Component = () => {
  4. const [useStateVar, setUseStateVar] = useState({});
  5. const { data } = useSWR("demo/data", fetcher, { refreshInterval: 1000 });
  6. // 创建一个 ref 以跟踪先前的数据值
  7. const prevDataRef = useRef();
  8. useEffect(() => {
  9. // 检查 prevDataRef.current 是否存在并且数据是否发生了变化
  10. if (prevDataRef.current && data !== prevDataRef.current) {
  11. // 仅在数据发生变化时更新 useStateVar
  12. setUseStateVar(prevState => {
  13. // 根据新数据修改状态
  14. // 例如,你可以将新数据与先前状态合并
  15. return { ...prevState, ...data };
  16. });
  17. }
  18. // 使用当前数据值更新 prevDataRef 以供下一次比较
  19. prevDataRef.current = data;
  20. }, [data]);
  21. // 组件其余代码
  22. return (
  23. // JSX 元素
  24. );
  25. }

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:

  1. import { useState, useEffect, useRef } from 'react';
  2. import useSWR from 'swr';
  3. const Component = () => {
  4. const [useStateVar, setUseStateVar] = useState({});
  5. const { data } = useSWR("demo/data", fetcher, { refreshInterval: 1000 });
  6. // Create a ref to keep track of the previous data value
  7. const prevDataRef = useRef();
  8. useEffect(() => {
  9. // Check if prevDataRef.current exists and if the data has changed
  10. if (prevDataRef.current && data !== prevDataRef.current) {
  11. // Update the useStateVar only when the data changes
  12. setUseStateVar(prevState => {
  13. // Modify the state based on the new data
  14. // For example, you can merge the new data with the previous state
  15. return { ...prevState, ...data };
  16. });
  17. }
  18. // Update the prevDataRef with the current data value for the next comparison
  19. prevDataRef.current = data;
  20. }, [data]);
  21. // Rest of your component code
  22. return (
  23. // JSX elements
  24. );
  25. }

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:

确定