useEffectOnce render twice with React.StrictMode
https://stackoverflow.com/questions/48846289/why-is-my-react-component-is-rendering-twice
Maybe a solution:
import {EffectCallback, useEffect, useRef} from 'react';
function useEffectOnce(effect: EffectCallback) {
const destroyFunc = useRef<void | any>();
const calledOnce = useRef(false);
const renderAfterCalled = useRef(false);
if (calledOnce.current) {
renderAfterCalled.current = true;
}
useEffect(() => {
if (calledOnce.current) {
return;
}
calledOnce.current = true;
destroyFunc.current = effect();
return () => {
if (!renderAfterCalled.current) {
return;
}
if (destroyFunc.current) {
destroyFunc.current();
}
};
}, []);
}
export default useEffectOnce;
I believe that this will only happen in development, not production which is by design with React 18 StrictMode changes.
I believe that this will only happen in development, not production which is by design with React 18 StrictMode changes.
Yes, definitely. But this being handled can avoid some problems for use cases of StrictMode in development (even not present in production). If the hook name is useEffectOnce and there is a way to "ignore this strictmode problem" why not?
This is affecting useThrottle too in #2343.
The very reason it happens in dev mode using <StrictMode> in React 18 is because it can happen in production mode. One way to look at it is that without upgrading useEffectOnce, react-use becomes a React 17 library.
Any chance we can get this fix into the library? I know there haven't been updates in a year or so but would love to see it work.
This simple implementation is what I'm using in my code:
const isLoaded = useRef(false);
useEffectOnce(() => {
console.log('(from the hooks lib, this does run twice in strict mode)!');
});
useEffect(() => {
if (isLoaded.current === false) {
isLoaded.current = true;
console.log('this only happens once, truly!');
}
})