【问题标题】:Custom hooks with dependency lists and eslint-plugin-react-hooks带有依赖列表和 eslint-plugin-react-hooks 的自定义钩子
【发布时间】:2020-05-22 15:15:31
【问题描述】:

我有一个关于 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 正确检测自定义挂钩的依赖列表问题? 甚至可以对自定义钩子进行这种检测吗?

【问题讨论】:

  • 为什么不能将apiCall作为依赖传入? (无论如何,它是从哪里来的?)如果该函数经常更改(这看起来很奇怪),您可以按照建议使用 useCallback 来记住它吗?

标签: reactjs react-hooks eslint eslint-plugin-react-hooks


【解决方案1】:

react-hooks/exhaustive-deps 规则允许您检查自定义挂钩。来自Advanced Configuration 选项:

exhaustive-deps 可以配置为验证自定义的依赖关系 带有附加钩子选项的钩子。此选项接受正则表达式 匹配具有依赖关系的自定义 Hook 的名称。

{   
  "rules": {
    // ...
    "react-hooks/exhaustive-deps": ["warn", {
      "additionalHooks": "(useMyCustomHook|useMyOtherCustomHook)"
    }]   
  }
} 

在您的.eslintrc 文件中,在“规则”配置中添加以下条目:

'react-hooks/exhaustive-deps': ['warn', {
      'additionalHooks': '(useApi)'
    }],

然后你应该能够调用你的钩子并看到 linter 警告并使用快速修复选项。

【讨论】:

    【解决方案2】:

    eslint-plugin-react-hooks 不支持自定义挂钩中的参数的依赖列表(据我所知)。 有一个 useCallback 的解决方法,正如 dangerismycat 建议的那样。

    所以不要这样做:

    const apiResult = useApi(() => apiCall(a, b, c), [a, b, c]);
    

    没有依赖列表参数的自定义钩子也可以实现相同的功能:

    const callback = useCallback(() => apiCall(a, b, c), [a, b, c]);
    const apiResult = useApi(callback);
    

    虽然它引入了更多样板并且代码更难阅读,但我并不介意。

    【讨论】:

    • 与 hooks.macro 配合得很好:const apiResult = useApi(useAutoCallback(() =&gt; apiCall(a, b, c))
    • 澄清一下,您可以将callback 传递给useEffect 的部门:const useApi = (cb) =&gt; { /* ... */ useEffect(() =&gt; { const result = cb(); doSomething(result); }, cb); /* ... */ }
    猜你喜欢
    • 2019-11-26
    • 2023-03-13
    • 2023-03-24
    • 2021-09-03
    • 2021-01-28
    • 1970-01-01
    • 2021-03-03
    • 2021-12-27
    • 2018-04-21
    相关资源
    最近更新 更多