Reputation: 2763
If I want useEffect
to only run once on component mount, what is the right way of doing it? Check the following example:
const UseEffectCounter1 = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, []);
return (
<div>
<button onClick={() => {setCount(count + 1)}}>+1</button>
</div>
)
}
Re-renders are prevented due to []
being passed as dependency array. Code running fine, no errors. 'You clicked 0 times' shows only once, click the button does nothing, which fits the purpose 'only run once on the component mount'.
However this is lying to React and not recommended in Dan Abramov's article here. I should pass the dependency to the dependency array, which is warned as React Hook useEffect has a missing dependency: 'count'
. However if I pass [count]
in the dependency array, useEffect
starts updating after component mount.
What is the correct way of making useEffect
only update on component mount?
Upvotes: 0
Views: 599
Reputation: 2679
As mentioned in the comment, there is no point in making the useEffect
hook dependent on the count
, if you are not going to update the title every time the count changes. The code could be:
const UseEffectCounter1 = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = 'You clicked 0 times';
}, []);
return (
<div>
<button onClick={() => {setCount(count + 1)}}>+1</button>
</div>
)
}
Anyway, if you really want to avoid the hard-coded value, you could do something like:
const UseEffectCounter1 = () => {
const initCount = 0;
const [count, setCount] = useState(initCount);
useEffect(() => {
document.title = `You clicked ${initCount} times`;
}, [initCount]);
return (
<div>
<button onClick={() => {setCount(count + 1)}}>+1</button>
</div>
)
}
As initCount
is never going to change, the useEffect hook will be triggered only once.
Upvotes: 2