Reputation: 956
I am trying to write my own reusable useEffect hook function useEffectOnce()
to run only once (on mount and unmount), but it seems impossible. My function is called after every re-render: https://codesandbox.io/s/mjx452lvox
function useEffectOnce() {
console.log("I am in useEffectOnce");
useEffect(() => {
console.log("I am in useEffectOnce's useEffect");
return () => {
console.log("i am leaving useEffectOnce's useEffect");
};
}, []);
}
function App() {
const [count, setCount] = useState(0);
useEffectOnce(); // once!?
return (
<div className="app">
<h3>useEffectOnce (my reusable function)... Wait, once!?</h3>
<button onClick={() => setCount(count + 1)}>
You clicked me {count} times
</button>
</div>
);
}
Notes:
useEffectOnce(() => {}, []);
changes nothing... and then big surprise, same behavior with reusable useState hook function(!?): https://codesandbox.io/s/2145m37xnr
My function useButton
is called after every re-render, and when is first, independent, button clicked.
function useButton(initialCounterValue) {
const [usebuttoncount, setUseButtonCount] = useState(initialCounterValue);
console.log("I am in useButton");
const handleuseButtonClick = () => {
setUseButtonCount(usebuttoncount + 1);
};
return {
usebuttoncount,
onClick: handleuseButtonClick
};
}
function App() {
const [count, setCount] = useState(0);
const useButtonCounter = useButton(0);
return (
<div className="app">
<h3>
useButton (my reusable useState function) is called only when... OMG!?
</h3>
<button onClick={() => setCount(count + 1)}>
You clicked me {count} times
</button>
<br />
<button {...useButtonCounter}>
(useButton hook) You clicked me {useButtonCounter.usebuttoncount} times
</button>
</div>
);
}
Upvotes: 1
Views: 493
Reputation: 222464
useEffectOnce
and useButton
are regular functions. They are expected to run on every component render. When component function is called, there's no way to prevent them from being called by conventional JavaScript means (i.e. with no eval
).
It's useEffect
callback function (I am in useEffectOnce's useEffect
log entry) that is expected to be called once on component mount. All code that needs to be evaluated on component mount should reside there.
Upvotes: 1