简体   繁体   中英

React useEffect hook missing dependencies linter warnings

I am using the React useEffect hook to obtain API data on component load, with the useAxios hook. The code is as below (simplified):

const [formData, setFormData] = useState<FormData>();   

const [{ , executeGet] = useAxios('', {
    manual: true,
});

const getFormData = async () => {
    let r = await executeGet({ url: `http://blahblahblah/`});
    return r.data;
};

useEffect(() => {
    const getData = async () => {
        try {
            let response = await getAPIData();
            if (response) {
                setFormData(response);
        } catch (e) {
            setFormError(true);
        }
    };
    getData();
}, []); 

This pattern is used frequently in the codebase, but I am getting the linter warning:

React Hook useEffect has missing dependencies: 'getFormData'. Either include them or remove the dependency array  react-hooks/exhaustive-deps

I can suppress the warning successfully with:

// eslint-disable-line react-hooks/exhaustive-deps

but it feels wrong to do this!

I can add constants to the dependency list without a problem, however when I add the getFormData function, I get an infinite loop. I have read around the area a lot and understand why the dependencies are needed. I am not sure if the useEffect hook is the best way to obtain the data, or whether there is a way to fetch data.

you should initiate getFormData function using useCallback hook and then put it in useEffect dependency list.

const getFormData = useCallback(async () => {
  let r = await executeGet({ url: `http://blahblahblah/`});
  return r.data;
}, [executeGet]);

you can read more about useCallback in reactjs site: https://reactjs.org/docs/hooks-reference.html#usecallback

The problem is that you are defining getFormData within the component. In each render, it is reassigned. As is, this would mean that your initial useEffect would only be bound to to first getFormData, not the one from the most recent render. This causes a warning because often this is not what you intend, particularly if your getFormData depended on state or props that could change.

The simplest solution in this case is to move the definition of your getFormData outside of your component, and use Axios directly instead of using a hook. That way it wouldn't need to be defined on every render anyways.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM