-
Notifications
You must be signed in to change notification settings - Fork 49.7k
Open
Description
React version: 19.1.0
Steps To Reproduce
mount this component, look at console. Refresh a few times.
Refreshing produces different output every time. it's fine that different numbers of renders happen due to behind-the-scenes batching, but my understanding is that renders and effects should be 1-to-1 with no dependency array.
I also have no idea why different values of timeout seem to be relevant.
Caused a real-world bug recently where I had a forceUpdate() in an event subscriber that was busy on init in a custom hook, with queries firing simultaneously to rerender the consumer of that hook.
import { useEffect, useReducer } from "react";
export default function App() {
const [_, forceUpdate] = useReducer((x) => !x, false);
useThrash();
console.log("RENDER");
useEffect(() => {
console.log("EFFECT");
});
useEffect(() => {
setTimeout(() => {
forceUpdate();
}, 10);
}, []);
}
const useThrash = () => {
const [_, forceUpdate] = useReducer((x) => !x, false);
useEffect(() => {
setTimeout(() => {
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
forceUpdate();
}, 1);
}, []);
};
https://codesandbox.io/p/sandbox/vyn5zj
expected: same number of renders and effect runs
actual: more renders than effect runs
example output:
RENDER
02:21:02.077 RENDER
02:21:02.081 EFFECT
02:21:02.085 RENDER
02:21:02.095 RENDER