Today I had a discussion with my colleague about React dependencies. He thought that all the variables that the components depend on for side effects should be put into the dependency array, for example
import React, { useContext, useEffect, useState } from 'react';
export const Component = props => {
const { someInfo } = props;
const [info, setInfo] = useState(null);
const { updateInfo } = useContext(someInfoContext);
const initSomething = async publicId => {
const res = await getPublicInfo(publicId);
updateInfo(res);
setInfo(res);
};
// Here only someInfo.publicId is used
useEffect(() => {
initSomething(someInfo.publicId);
}, [someInfo.publicId]);
return <div>hellp world</div>;
};
Here, the side effect in useEffect depends on the variable someInfo.publicId, so I put it in the dependency array to ensure that the side effect can be re-executed every time it changes. However, my colleague disagrees. He thinks that all the variables in useEffect are variable dependencies, so he thinks it should be written like this
import React, { useCallback, useContext, useEffect, useState } from 'react';
export const Component = props => {
const { someInfo } = props;
const [info, setInfo] = useState(null);
const { updateInfo } = useContext(someInfoContext);
const initSomething = useCallback(
async publicId => {
const res = await getPublicInfo(publicId);
updateInfo(res);
setInfo(res);
},
[updateInfo]
);
// Here someInfo.publicId and initSomething are used
useEffect(() => {
initSomething(someInfo.publicId);
}, [someInfo.publicId, initSomething]);
return <div>hellp world</div>;
};
I think there is a disadvantage of writing like this, that is, the dependency is contagious. The reference of the function must be guaranteed to be unchanged, so the function must be wrapped with useCallback, and updateInfo in initSomething must also be processed with useCallback. This needs to be processed all the time, which brings a lot of mental burden, and the code is prone to problems and infinite loops. However, if it is like what I wrote first, initSomething will be re-declared when the component renders, but it can be guaranteed that there is no problem with the code execution logic.
I want to know which of the first and second ways of writing is correct?