Пользовательские хуки со списками зависимостей и eslint-plugin-react-hooks
У меня вопрос по поводу eslint-plugin-react-hooks.
Я хотел сократить шаблонный код выполнения вызова API и сохранения результата в состоянии, поэтому я создал собственный хук:
export const loading = Symbol('Api Loading');
export const responseError = Symbol('Api Error');
export function useApi<T>(
apiCall: () => CancelablePromise<T>,
deps: DependencyList
): T | (typeof loading) | (typeof responseError) {
const [response, setResponse] = useState<T | (typeof loading) | (typeof responseError)>(loading);
useEffect(() => {
const cancelablePromise = apiCall();
cancelablePromise.promise
.then(r => setResponse(r))
.catch(e => {
console.error(e);
setResponse(responseError);
});
return () => cancelablePromise.cancel();
}, deps); // React Hook useEffect has a missing dependency: 'apiCall'. Either include it or remove the dependency array. If 'apiCall' changes too often, find the parent component that defines it and wrap that definition in useCallback (react-hooks/exhaustive-deps)
return response;
}
Теперь кастомный хук работает отлично, а вот хуки eslint-plugin-react-hooks - не очень. Предупреждение в моем коде - не большая проблема. Я знаю, что могу отключить это предупреждение, добавив комментарий:
// eslint-disable-next-line react-hooks/exhaustive-deps
Проблема в том, что один из настраиваемых аргументов ловушки - это список зависимостей, и доза eslint-plugin-react-hooks не обнаруживает недостающие зависимости от него. Как заставить eslint-plugin-react-hooks правильно определять проблемы со списком зависимостей для моего пользовательского хука? Возможно ли вообще такое обнаружение для кастомных хуков?
2 ответа
Похоже, что списки зависимостей в качестве аргументов в пользовательских хуках не поддерживаются в eslint-plugin-react-hooks (насколько мне известно). Существует обходной путь с использованием useCallback, как предлагает dangerousismycat.
Итак, вместо того, чтобы делать:
const apiResult = useApi(() => apiCall(a, b, c), [a, b, c]);
Та же функциональность может быть достигнута без настраиваемого хука, имеющего аргумент списка зависимостей:
const callback = useCallback(() => apiCall(a, b, c), [a, b, c]);
const apiResult = useApi(callback);
Хотя жаль, что он вводит немного больше шаблонов и код немного труднее читать, я не слишком против.
The
react-hooks/exhaustive-deps
правило позволяет вам проверять ваши пользовательские хуки. Из параметров расширенной конфигурации :
исчерпывающий-депс может быть настроен для проверки зависимостей пользовательских хуков с опцией AdditionalHooks. Эта опция принимает регулярное выражение для соответствия именам пользовательских хуков, которые имеют зависимости.
{ "rules": { // ... "react-hooks/exhaustive-deps": ["warn", { "additionalHooks": "(useMyCustomHook|useMyOtherCustomHook)" }] } }
В твоей
.eslintrc
файле, добавьте следующую запись в конфиг «rules»:
'react-hooks/exhaustive-deps': ['warn', {
'additionalHooks': '(useApi)'
}],
Затем вы сможете вызвать свой хук, увидеть предупреждение линтера и использовать опцию Quick Fix.