Skip to content

Instantly share code, notes, and snippets.

@cosemansp
Created August 26, 2022 12:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cosemansp/5964bf9145b0910eb8d36cf3026c7333 to your computer and use it in GitHub Desktop.
Save cosemansp/5964bf9145b0910eb8d36cf3026c7333 to your computer and use it in GitHub Desktop.
import * as React from 'react';
// To avoiding Use Effect Getting Called Twice
// See https://dev.to/ag-grid/react-18-avoiding-use-effect-getting-called-twice-4i9e
export const useMount = (effect: () => void | (() => void)) => {
const destroyFunc = React.useRef<void | (() => void)>();
const effectCalled = React.useRef(false);
const renderAfterCalled = React.useRef(false);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [val, setVal] = React.useState<number>(0);
if (effectCalled.current) {
renderAfterCalled.current = true;
}
React.useEffect(() => {
// only execute the effect first time around
if (!effectCalled.current) {
destroyFunc.current = effect();
effectCalled.current = true;
}
// this forces one render after the effect is run
setVal((currentVal) => currentVal + 1);
return () => {
// if the comp didn't render since the useEffect was called,
// we know it's the dummy React cycle
if (!renderAfterCalled.current) {
return;
}
if (destroyFunc.current) {
destroyFunc.current();
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment