I have a question regarding eslint-plugin-react-hooks.
I wanted to reduce the boilerplate code of doing a API call and storing the result into state so I created a custom hook:
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;
}
Now the custom hook works great but the eslint-plugin-react-hooks not so much. The warning in my code is not a big problem. I know i can silence this warning by adding a comment:
// eslint-disable-next-line react-hooks/exhaustive-deps
The problem is that one of the custom hook arguments is a dependency list and eslint-plugin-react-hooks dose not detect missing dependencies on it. How do I make eslint-plugin-react-hooks correctly detect dependency list problems for my custom hook? Is it even possible to have such detection for custom hooks?
The react-hooks/exhaustive-deps
rule allows you to check your custom hooks. From the Advanced Configuration options:
exhaustive-deps can be configured to validate dependencies of custom Hooks with the additionalHooks option. This option accepts a regex to match the names of custom Hooks that have dependencies.
{ "rules": { // ... "react-hooks/exhaustive-deps": ["warn", { "additionalHooks": "(useMyCustomHook|useMyOtherCustomHook)" }] } }
In your .eslintrc
file, add the following entry in the "rules" config:
'react-hooks/exhaustive-deps': ['warn', {
'additionalHooks': '(useApi)'
}],
Then you should be able to call your hook and see the linter warning and use the Quick Fix option.
Looks like the dependency lists as arguments in custom hooks are not supported in eslint-plugin-react-hooks (as far as i know). There is a workaround with useCallback as dangerismycat suggested.
So instead of doing:
const apiResult = useApi(() => apiCall(a, b, c), [a, b, c]);
The same functionality can be achieved without the custom hook having a dependency list argument:
const callback = useCallback(() => apiCall(a, b, c), [a, b, c]);
const apiResult = useApi(callback);
While its a shame that it introduces a bit more boilerplate and the code is a bit harder to read, I don't mind it too much.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With