javascript 无法在setInterval React功能组件中获取更新的属性

zc0qhyus  于 2023-02-15  发布在  Java
关注(0)|答案(2)|浏览(151)

我无法在Component1内的setInterval中获取更新的属性,它给我的是旧值
下面是我正在使用的代码:

import { useState, useEffect } from "react";
import "./styles.css";

export default function App() {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    const intervalID = setInterval(() => {
      setCounter((counter) => counter + 1);
    }, 1000);

    return () => {
      clearInterval(intervalID);
    };
  }, []);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Component1 counter={counter} />
    </div>
  );
}

const Component1 = ({ counter }) => {
  useEffect(() => {
    const intervalID = setInterval(() => {
      console.log(counter);
    }, 1000);

    return () => {
      clearInterval(intervalID);
    };
  }, []);
  return <h1>Component1 count: {counter}</h1>;
};

在Component1内的这段代码中,计数器的值在浏览器上每秒更新一次,但在setInterval内的console.log上,我总是得到初始值,而不是更新后的值。
我还得到了一个解,看起来像这样

import { useState, useEffect, useRef } from "react";
import "./styles.css";

export default function App() {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    const intervalID = setInterval(() => {
      setCounter((counter) => counter + 1);
    }, 1000);

    return () => {
      clearInterval(intervalID);
    };
  }, []);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Component1 counter={counter} />
    </div>
  );
}

const Component1 = ({ counter }) => {
  const counterRef = useRef(null);
  counterRef.current = counter;
  useEffect(() => {
    const intervalID = setInterval(() => {
      console.log(counterRef.current);
    }, 1000);

    return () => {
      clearInterval(intervalID);
    };
  }, []);
  return <h1>Component1 count: {counter}</h1>;
};

但是在这个解决方案中,我必须使用额外的内存空间,因为我创建了一个ref并给它赋值。

是否有更好的解决方案来获取setInterval内的更新值,以正确的方式完成此操作。

sxissh06

sxissh061#

您可以在以下场景中尝试此方法:您将面临JavaScript闭包行为,

useEffect(() => {
    const intervalId = setInterval(() => {
      console.log('count is', counter);
    }, 1000);

    return () => clearInterval(intervalId);
  }, [counter]);

但在您的场景中,这将更适合于Component1,

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

ppcbkaq52#

在这种情况下:* * 在第一次渲染时**您设置了一个间隔,每秒在控制台上打印0

useEffect(() => {
    const intervalID = setInterval(() => {
      console.log(counter);
    }, 1000);

    return () => {
      clearInterval(intervalID);
    };
  }, []);

我编辑您的代码:

import { useState, useEffect } from "react";

export default function App() {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    const intervalID = setInterval(() => {
      setCounter((counter) => counter + 1);
    }, 1000);

    return () => {
      clearInterval(intervalID);
    };
  }, []);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Component1 counter={counter} />
    </div>
  );
}

const Component1 = ({ counter }) => {
  useEffect(() => {
    console.log(counter);
  }, [counter]);
  return <h1>Component1 count: {counter}</h1>;
};

在这种情况下,在组件1中:当计数器的值改变时,console.log打印新值

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

阅读关于useEffect的信息
如果你想在一个属性改变时执行一个方法,你可以使用useEffect,并且你必须像下面的代码一样在闭包中传递该属性:

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

我将counter传递给useEffect,当它发生变化时,useEffect使用新值运行console.log

相关问题