Пользовательские хуки со списками зависимостей и 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.

Другие вопросы по тегам