0

这是我的错误:“'setPartData' 函数使 useEffect Hook 的依赖项(在第 44 行)在每次渲染时都会发生变化。将其移动到 useEffect 回调中。或者,将 'setPartData' 定义包装到它自己的 useCallback() Hook 中。 eslint(react-hooks/exhaustive-deps)"

我应该如何最好地解决这个问题,因为我无法从数组中删除 url 和 setPartData 并禁用 eslint 规则。

    /* 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;
};

我尝试了 useCallBack() 钩子,但我似乎在创建一个无限循环时错误地实现了它。任何帮助,将不胜感激。

4

1 回答 1

1

setPartData在 useEffect 钩子中移动你的声明,并使用函数版本setData

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

如果您也需要钩子之外的 setPartData 函数,请使用useCallback它使其在每次渲染时都不会更改

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

这是完整的 useEffect 和里面定义的 setPartData

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]);
于 2020-10-09T21:07:32.630 回答