In my component, I have the following (for brevity I've only included relevant code snippets):
const authContext = useAuthContext();
const projectContext = useProjectContext();
useEffect(() => {
const loadProject = async (userId: string) => {
await projectContext.loadProjectsForUser(userId);
}
if (authContext.user) {
loadProject(authContext.user.id).catch().finally();
}
}, [authContext.user]);
However, eslint tells me:
React Hook React.useEffect has a missing dependency: 'projectContext'. Either include it or remove the dependency array.
Can I ignore this or do I need to add projectContext
to the dependency list? It has a bunch of other values, so wouldn't this get called each time one of those updates? What's the best way to resolve this?
Thanks
CodePudding user response:
1,just add projectContext
to effect dep array, this will trigger effect when projectContext
changes, if projectContext
never change this way is fine
2, as @Oleg pointed, Move function const loadProject = async (userId: string) => { await projectContext.loadProjectsForUser(userId); }
out of useeffect, then projectContext
wont update when it is updated, because it will use the value in first render (effect function is not updated when prop/context change), if projectContext
never change this way is fine
3, use ref to store projectContext
when it's updated, then you do not add dep array, just a ref and another effect
const authContext = useAuthContext();
const projectContext = useProjectContext();
let ref = createRef(projectContext.loadProjectsForUser)
useEffect(() => {
const loadProject = async (userId: string) => {
await ref.current(userId);
}
if (authContext.user) {
loadProject(authContext.user.id).catch().finally();
}
}, [authContext.user]);
useEffect(()=>{
ref.current = projectContext.loadProjectsForUser
},[projectContext.loadProjectsForUser])
CodePudding user response:
You can destructure authContext and projectContext to get only the value you needed in component. Then you can mention only those values which is used in useEffect in dependency array.
const {user} = useAuthContext();
const {loadProjectsForUser} = useProjectContext();
const {id:userId} = user;
useEffect(() => {
// Some code here
}, [userId, loadProjectsForUser])
CodePudding user response:
Yes, you'll need to add projectContext
to the dependencies, and to make sure it doesn't trigger a project reload on every change inside projectContext
you can update your if
statement to something like:
if (authContext.user && projectNotLoaded) { // ... }
Shifting the function out of useEffect won't help in this instance.. you'll just have to add the new function to dependencies and it'll fire on every render.
To stop that you'd have to put the new function into a useCallback()
which will require the projectContext
as a dependency anyway, so you've just shifted the problem.
As to why you'll want to include projectContext
with your dependencies there's a great explanation here:
https://betterprogramming.pub/stop-lying-to-react-about-missing-dependencies-10612e9aeeda