In my React Native app, i'm using a dependency array in my useEffect and want to rerender when the value changes. But i want the rerendering to happen after 2 or 3 seconds. Currently it rerenders instantly which is adding some flickering issue in my app. Now, here's my useEffect currently:
useEffect(() => {
fetchClimate();
setCount(count + 1);
if (rooms.length >= 1 && count < 2 && displayRoomList) {
setActive(rooms[0].id);
}
const interval = setInterval(() => {
fetchClimate();
}, 10000);
return () => clearInterval(interval);
}, [rooms]);
Whenever the value of room changes from a button press, useEffect is called instantly. I want this to be called after 2 or 3 seconds of when the room data changes. How can i do that?
It's most likely the wrong solution to purposefully wait several seconds as you're probably creating new race conditions. If you really want to do that you would need to run the code that produces the change in the UI in a setTimeout for 3000 ms.
https://developer.mozilla.org/en-US/docs/Web/API/setTimeout
setTimeout(() => {console.log("Code here runs after 3 seconds")}, 3000);
However, the real answer is that you need to solve for why the instaneous reload looks bad. Forcing your code wait is likely to introduce race conditions (causing more difficult to solve bugs) and creates a poor user experience. You might be able to get away with it this time, but as soon as you have another similar problem this solution becomes untenable. Other Possible solutions:
If your code is waiting for another asynchronous change you could to add that as a dependency to the useEffect and place the UI changing code in an if statement.
If the layout update itself looks jarring, try using React Native's LayoutAnimation. This automatically animates layout changes but can be kind of hit or miss. https://reactnative.dev/docs/layoutanimation
if (
Platform.OS === "android" &&
UIManager.setLayoutAnimationEnabledExperimental
) {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
useEffect(() => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);
//Run UI changing code
}, [rooms])
And finally if you're having issues with your code running before other layout changes are completed, you could try changing useEffect to useLayoutEffect https://reactjs.org/docs/hooks-reference.html#uselayouteffect
Ultimately, there is almost always a better solution than using setTimeout