Being Honest About Your useEffect dependencies
useEffect is great, it's my absolute favourite Hook but it's got one major rule: BE HONEST ABOUT YOUR DEPENDENCIES. If you're dishonest your linting will kick in and yell at you. I know what you're thinking "what if I want to mimic ComponentDidMount", still be honest.
The thing you have to remember is that useEffect acts as both componentDidMount
and componentDidUpdate
if you're dishonest you'll end up with unexpected behaviour.
Take this example, say you want to make an API call when:
- The component mounts
- the user changes a value
let's say we're dishonest about our dependencies, it'll look like this
import React, {useEffect} from "react";
function App({id}){
useEffect(()=> {
axios.get(`https://dummydata/user/${id})`).then(resp=> console.log(resp)).catch(err=> console.error(err));
},[]) // we're being dishonest we have a dependency on props.id
}
export default App;
what do you think will happen ? sure we initially get back data but when the user changes the prop id
we never refetch data because useEffect
never re-runs.
Let's see what being honest looks like
import React, {useEffect} from "react";
function App({id}){
useEffect(()=> {
axios.get(`https://dummydata/user/${id})`).then(resp=> console.log(resp)).catch(err=> console.error(err));
},[id])
}
export default App;
Now when props change useEffect runs again and the data is fetched, no unexpected behaviour. In conclusion, it's easy to be dishonest especially when you just want to do some async stuff when the component mounts, but remember always be honest, future you will thank you for it.