简体   繁体   中英

Best way to resolve react-hooks/exhaustive-deps

Here is my error: "The 'setPartData' function makes the dependencies of useEffect Hook (at line 44) change on every render. Move it inside the useEffect callback. Alternatively, wrap the 'setPartData' definition into its own useCallback() Hook.eslint(react-hooks/exhaustive-deps)"

How should I best resolve this as I am unable to remove the url and setPartData from the array and disable the eslint rule.

    /* eslint-disable no-shadow */
import { useState, useEffect } from 'react';

export const apiStates = {
    LOADING: 'LOADING',
    SUCCESS: 'SUCCESS',
    ERROR: 'ERROR',
};

/**
 *
 * @param {*} url
 */
export const useApi = (url) => {
    const [data, setData] = useState({
        state: apiStates.LOADING,
        error: '',
        data: [],
    });
    /**
     *
     * @param {*} partialData
     */
    const setPartData = (partialData) => setData({ ...data, ...partialData });

    useEffect(() => {
        setPartData({
            state: apiStates.LOADING,
        });
        fetch(url)
            .then((response) => response.json())
            .then((data) => {
                setPartData({
                    state: apiStates.SUCCESS,
                    data,
                });
            })
            .catch((err) => {
                setPartData({
                    state: apiStates.ERROR,
                    error: err,
                });
            });
    }, [url, setPartData]);

    return data;
};

I tried to the useCallBack() hook, but I seem to be implementing it incorrectly as I'm creating an infinite loop. Any help would be appreciated.

Move your declaration of setPartData within the useEffect hook, and use the function version of the setData

const setPartData = (partialData) => setData((data) => ({ ...data, ...partialData }));

If you need the setPartData function outside of the hook too, use useCallback to make it not change on each render

const setPartData = useCallback((partialData) => setData((data) => ({ ...data, ...partialData })),[]);

Here's the complete useEffect with the setPartData defined inside

useEffect(() => {
    /**
     * @param {Partial<typeof data>} partialData
     */
    const setPartData = (partialData) =>
      setData((data) => ({ ...data, ...partialData }));
    setPartData({
      state: apiStates.LOADING,
    });
    fetch(url)
      .then((response) => response.json())
      .then((data) => {
        setPartData({
          state: apiStates.SUCCESS,
          data,
        });
      })
      .catch((err) => {
        setPartData({
          state: apiStates.ERROR,
          error: err,
        });
      });
  }, [url]);

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