useEffectOnce
Hook to executes effect and clean up after component mount only once. It prevents React 18 StrictMode behavior if present, otherwise it works like a normal useEffect with empty dependencies array.
N.B. Not use in a component with normal useEffect, if it executes a React.DispatchAction, because this action is executes twice if there is React.StrictMode.
Demo
INFO
The component has:
- a Child1 component with a messages useState variable and useEffect that sets a message for effect and clean up executions.
- a Child2 component with a messages useState variable and useEffectOnce that sets a message for effect and clean up executions.
Since React 18 StrictMode executes effects twice (mount - unmount - mount), the useEffect will print run effect message twice, useEffectOnce no.
Loading demo…
Show source code
tsx
import { useEffect, useState } from "react";
import { useEffectOnce } from "../../../..";
const Child1 = () => {
const [messages, setMessages] = useState<string[]>([]);
useEffect(() => {
setMessages(m => ([...m, "run effect"]));
return () => {
setMessages(m => ([...m, "run clean up function effect"]));
}
}, []);
return (<div>
<p><strong>UseEffect</strong></p>
{messages.map((mess, index) => <p key={index}>{mess}</p>)}
</div>);
}
const Child2 = () => {
const [messages, setMessages] = useState<string[]>([]);
useEffectOnce(() => {
setMessages(m => ([...m, "run effect"]));
return () => {
setMessages(m => ([...m, "run clean up function effect"]));
}
});
return (<div>
<p><strong>UseEffectOnce</strong></p>
{messages.map((mess, index) => <p key={index}>{mess}</p>)}
</div>);
}
const UseEffectOnce = () => {
return (
<div style={{ display: "grid", gridTemplateColumns: "auto auto", justifyContent: "center", gap: 50 }}>
<Child1 />
<Child2 />
</div>
);
};
UseEffectOnce.displayName = "UseEffectOnce";
export { UseEffectOnce };