admin管理员组文章数量:1332395
I'm trying to change my text every 3 seconds using useEffect() and setInterval(). 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"
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>)}
I'm trying to change my text every 3 seconds using useEffect() and setInterval(). 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"
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>)}
Share
Improve this question
asked Dec 30, 2020 at 9:17
gospeid12gospeid12
1,0123 gold badges14 silver badges27 bronze badges
3
-
You're closing over the
toggle
state inside of your setInterval callback, maybe consider using useInterval hook by Dan: overreacted.io/making-setinterval-declarative-with-react-hooks (or perhaps a ref). Also worth looking at this question posted yesterday and. its answer – Nick Parsons Commented Dec 30, 2020 at 9:21 -
Try something like this instead:
useEffect(() => { setTimeout(() => setToggle(prevToggle => !prevToggle), 3000) }, [toggle]);
the timed out function should get the new toggle value each time – Jayce444 Commented Dec 30, 2020 at 9:26 - It actually worked when i removed the [toggle] in the end of useEffect function. Why is that? I thought that it should listen to toggle variable to work? @Jayce444 – gospeid12 Commented Dec 30, 2020 at 9:34
2 Answers
Reset to default 6Solution:
useEffect(() => {
const intervalID = setInterval(() => {
setToggle((toggle) => !toggle)
}, 3000);
return () => clearInterval(intervalID);
}, []);
Important points:
- The dependency array
[]
should be empty. This way you ensure that you're gonna execute this effect only on the initial mounting of the ponent. You need only a single interval and its creation and destruction are not dependent on a single variable but the ponent itself. If you puttoggle
in the dependency array, you will run this effect every time the variable changes thus effectively making YET ANOTHER interval on every 3 seconds. If you did supply a clean-up function, this would still work but it would be more like asetTimeout
. However, in your case (without a clean-up function), this will simply introduce infinite number of intervals which will pete with each other. - You have to supply an updater function to
setToggle
instead of a simple value. This ensures that you're using the most current state for the update and not the stale one in the closure. 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 initialfalse
totrue
and this will repeat forever, leaving you with a "constant"true
value. - As you're using an interval, you should provide a clean-up function to the
useEffect
to clear the interval on ponent dismount. This is very important as skipping this part will introduce memory leaks and also bugs as you'll try to update a ponent even after its dismount from the DOM.
Try this way
useEffect(() => {
setTimeout(() => setToggle((prevToggle) => !prevToggle), 3000);
}, [toggle]);
本文标签: javascriptChange text every 3 seconds React useEffectStack Overflow
版权声明:本文标题:javascript - Change text every 3 seconds React useEffect - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742283804a2446573.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论