+ 10

Problem with React context API and useEffect hook

Hey everybody. So I have a timer component and 4 option components. I want behavior that if timer is out of time then it should move to next question and same thing + timer set to 0 should happen if any option is clicked. It works fine with timer, like if it runs out of time then next question is displayed but once I use option button then it behaves different and timer also runs twice speed. Here is my code, please can anyone check out where did I make mistakes? https://code.sololearn.com/W6g76LukrNky/?ref=app

22nd May 2020, 1:11 PM
Raj Chhatrala
Raj Chhatrala - avatar
25 Réponses
+ 10
As suggested by calvin: Different useEffect for timer and currentIndex. I used setInterval instead of setTimeout https://code.sololearn.com/WsU4oM3cEBi6/?ref=app
22nd May 2020, 3:05 PM
Burey
Burey - avatar
+ 8
Putting the interval/timeout value in the hook state just ensures that we have the updated value. you can test this code to see what happens when declaring the value without useState: https://code.sololearn.com/WY3PM3Qj82Z1/?ref=app If you don't need to control the clear functions from within the component you can use a unmount useEffect and initialize the interval in there (and return a function that clears it)
22nd May 2020, 4:15 PM
Burey
Burey - avatar
+ 7
🔫 Rick Grimes better use separate useEffect for timer and currentIndex.
22nd May 2020, 2:43 PM
Calviղ
Calviղ - avatar
+ 7
🔫 Rick Grimes timeouts and intervals can be tricky with hooks (and in react lifecycles in general)
22nd May 2020, 3:13 PM
Burey
Burey - avatar
+ 5
Calviղ the variable name is timerInterval, but the functions are setTimeout and clearTimeout 😂
22nd May 2020, 1:48 PM
Gordon
Gordon - avatar
+ 5
Don't be afraid of having multiple useEffect hooks Just try to keep them as tidy as possible
22nd May 2020, 2:57 PM
Burey
Burey - avatar
+ 4
How about hositing the timer to a global level. Explicitly, adding the timer variable to the reducer state, and reseting to 0 inside the dispatch SET_QUESTION type?
22nd May 2020, 2:21 PM
Gordon
Gordon - avatar
+ 4
🔫 Rick Grimes since it's setTimeout, you can safely clearTimeout whenever useEffect runs, no need to check for timerTimeout!=null
22nd May 2020, 2:40 PM
Calviղ
Calviղ - avatar
+ 4
Calviղ Okay let me try that way and see if I can solve it otherwise I'll have to go by way suggested by Gordon I actually thought about that way but then I thought it might be not the best way to do it, so dropped that idea 😬
22nd May 2020, 2:47 PM
Raj Chhatrala
Raj Chhatrala - avatar
+ 3
If you put setInterval in useEffect with timer trigger, the timer speed would be double whenever timer is triggered. You can use setTimeout instead, let timer retriggers the interval.
22nd May 2020, 1:43 PM
Calviղ
Calviղ - avatar
+ 3
Calviղ sorry, my bad. I was trying to do this with interval but after some Google search I found this way and I forgot to change variable name Gordon Do i have to use multiple useEffects?
22nd May 2020, 1:57 PM
Raj Chhatrala
Raj Chhatrala - avatar
+ 3
🔫 Rick Grimes i notice currentIndex is increment when option is selected, and it triggers useEffect function running. Should currentIndex triggered, run clearTimeout while the timeout is still counting? instead of setting setTimeout again.
22nd May 2020, 2:02 PM
Calviղ
Calviղ - avatar
+ 3
🔫 Rick Grimes I noticed that timerTimeout is always null, so currentIndex has no way to clearTimeout.
22nd May 2020, 2:34 PM
Calviղ
Calviղ - avatar
+ 3
I tried to edit code as Gordon suggested, the only problem now is that once I use option to change question index then timer is running at twice speed. https://code.sololearn.com/WwiPUR4UaKN8/?ref=app
22nd May 2020, 2:58 PM
Raj Chhatrala
Raj Chhatrala - avatar
+ 3
🔫 Rick Grimes did you clearTimeout when currentIndex triggered?
22nd May 2020, 3:06 PM
Calviղ
Calviղ - avatar
+ 3
🔫 Rick Grimes I think timerTimeout should be in global state too..
22nd May 2020, 3:09 PM
Calviղ
Calviղ - avatar
+ 3
Burey okay that's pretty neat example. I never thought of making it that way. Thank you so much for that.
22nd May 2020, 3:12 PM
Raj Chhatrala
Raj Chhatrala - avatar
+ 3
Calviղ issue is solved but still I tried to do clearTimeout for currentIndex useEffect which causes timer to never start (just updated code) Calvin and Gordon thanks to you two for taking some time for me. :)
22nd May 2020, 3:12 PM
Raj Chhatrala
Raj Chhatrala - avatar
+ 3
Yes, indeed it is. I almost wasted 2 hours looking for solution
22nd May 2020, 3:16 PM
Raj Chhatrala
Raj Chhatrala - avatar
22nd May 2020, 1:41 PM
Gordon
Gordon - avatar