Skip to content

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 };

Released under the MIT License.