I know the useEffect
hook with an empty dependency array is the equivalent (but not the same) to the componentDidMount
life cycle hook. I also know that useEffect
should include all dependencies in the array, which may or may not cause additional unintended renders.
So I've read about how useReducer
is the cheat mode of hooks for cases where you want to reference an external value without that value triggering a re-render. I want to know the effective differences between putting an effect in a reducer function compared to calling it in useEffect
with intentionally left out dependencies.
Take the following example (omitted returns for brevity). Let's assume the goal is to perform an action only with the initial count given to the component, while allowing the count to change freely.
// Component mounting with a suppressed warning
function ComponentFoo(props) {
const { count } = props;
useEffect(() => {
console.log("Component mounted with count", count);
}, []); // eslint-disable-line
}
// Component mounting without warnings
function ComponentBar(props) {
const { count } = props;
const [, dispatchMount] = useReducer(() => {
console.log("Component mounted with count", count);
}, undefined);
useEffect(dispatchMount, []);
}
From what I can tell, the above two components create the same results — They mount and log only the initial value of count
without logging changes to it. While I feel the second approach is much more "correct" because it doesn't require suppressing an ESLint warning, is it really any different? Are there any caveats to doing the former that aren't also present in the latter?
Is this latter use of useReducer
a poor pattern altogether, and if so, how would you instead achieve the result? I do have a feeling that this may be abusing useReducer
in some way since it ignores the state aspect of it.
Perhaps it is a viable solution to create some state using the initial value and pass that as a legitimate dependency to useEffect
? (Even though this perhaps needlessly duplicates the value)
// Component mounting without warnings
function ComponentBaz(props) {
const [count] = useState(props.count);
useEffect(() => {
console.log("Component mounted with count", count);
}, [count]);
}
I'd be interested to hear your thoughts on this and what solutions are appropriate, thanks.