简体   繁体   English

每 3 秒更改一次文本 React useEffect

[英]Change text every 3 seconds React useEffect

I'm trying to change my text every 3 seconds using useEffect() and setInterval().我正在尝试使用 useEffect() 和 setInterval() 每 3 秒更改一次文本。 Right now it only changes the text ONE time then it doesn't change it anymore.现在它只更改一次文本,然后不再更改它。 What am i doing wrong?我究竟做错了什么?

EDIT: I'm using the library "react-spring"编辑:我正在使用库“react-spring”

  const [toggle, setToggle] = useState(false)

  useEffect(() => {
    setInterval(() => {
      switch (toggle) {
        case false: setToggle(true)
        break;
        case true: setToggle(false)
        break;
      }
    }, 3000);
  }, [])

{transitions.map(({ item, props }) => item
  ? <animated.div style={props}>Text that changes #1</animated.div>
  : <animated.div style={props}>Text that changes #2</animated.div>)}

Solution:解决方案:

useEffect(() => {
    const intervalID = setTimeout(() =>  {
        setToggle((toggle) => !toggle)
    }, 3000);

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

Important points:要点:

  1. The dependency array( [] ) should be empty.依赖数组( [] )应该是空的。 This way you ensure that you're gonna execute this effect only on the initial mounting of the component.这样,您可以确保仅在组件的初始安装时执行此效果。 You need only a single interval and its creation and destruction are not dependent on a single variable but the component itself.您只需要一个间隔,它的创建和销毁不依赖于单个变量,而是依赖于组件本身。 If you put toggle in the dependency array, you will run this effect every time the variable changes thus effectively making YET ANOTHER interval on every 3 seconds.如果您在依赖数组中放置toggle ,您将在每次变量更改时运行此效果,从而有效地每 3 秒产生一次间隔。 If you did supply a clean-up function, this would still work but it would be more like a setTimeout .如果您确实提供了清理 function,这仍然可以工作,但它更像是setTimeout However, in your case(without a clean-up function), this will simply introduce infinite number of intervals which will compete with each other.但是,在您的情况下(没有清理功能),这只会引入无限数量的间隔,这些间隔将相互竞争。
  2. You have to supply an updater function to setToggle instead of a simple value.您必须提供更新程序 function 来setToggle而不是简单的值。 This ensures that you're using the most current state for the update and not the stale one in the closure.这可确保您使用最新的 state 进行更新,而不是关闭中的旧版本。 If you simply provide a value, the interval is making a closure over your initial value and thus updating it.如果您只是提供一个值,则间隔将关闭您的初始值并因此对其进行更新。 In this way, you will always update the initial false to true and this will repeat forever, leaving you with a "constant" true value.这样,您将始终将初始false更新为true ,这将永远重复,为您留下一个“恒定”的true值。
  3. As you're using an interval, you should provide a clean-up function to the useEffect to clear the interval on component dismount.当您使用间隔时,您应该向 useEffect 提供清理useEffect以清除组件卸载的间隔。 This is very important as skipping this part will introduce memory leaks and also bugs as you'll try to update a component even after its dismount from the DOM.非常重要,因为跳过这部分会引入 memory 泄漏和错误,因为即使在组件从 DOM 中卸载后,您也会尝试更新组件。

Try this way试试这个方法

useEffect(() => {
  setTimeout(() => setToggle((prevToggle) => !prevToggle), 3000);
}, [toggle]);

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

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