#reactjs #react-hooks #usecallback
#reactjs #перехваты реакции #usecallback
Вопрос:
Вот моя ошибка: «Функция ‘setPartData’ изменяет зависимости useEffect Hook (в строке 44) при каждом рендеринге. Переместите его внутрь обратного вызова useEffect. В качестве альтернативы, оберните определение ‘setPartData’ в его собственный useCallback () Hook.eslint(реагирующие крючки / исчерпывающий-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(), но, похоже, я неправильно его реализую, поскольку создаю бесконечный цикл. Любая помощь будет оценена.
Ответ №1:
Переместите ваше объявление setPartData
в ловушку useEffect и используйте функциональную версию setData
const setPartData = (partialData) => setData((data) => ({ ...data, ...partialData }));
Если вам также нужна функция setPartData вне хука, используйте useCallback
, чтобы она не менялась при каждом рендеринге
const setPartData = useCallback((partialData) => setData((data) => ({ ...data, ...partialData })),[]);
Вот полный эффект использования с 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]);