You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

38 lines
955 B

import { useEffect, useRef, useState } from "react";
export const useEffectOnce = (effect) => {
const effectFn = useRef(effect);
const destroyFn = useRef();
const effectCalled = useRef(false);
const rendered = useRef(false);
const [, setVal] = useState(0);
if (effectCalled.current) {
rendered.current = true;
}
useEffect(() => {
// only execute the effect first time around
if (!effectCalled.current) {
destroyFn.current = effectFn.current();
effectCalled.current = true;
}
// this forces one render after the effect is run
setVal((val) => val + 1);
return () => {
// if the comp didn't render since the useEffect was called,
// we know it's the dummy React cycle
if (!rendered.current) {
return;
}
// otherwise this is not a dummy destroy, so call the destroy func
if (destroyFn.current) {
destroyFn.current();
}
};
}, []);
};