javascript - 设计 React Hooks 防止 react-hooks/exhaustive-deps 警告

标签 javascript reactjs functional-programming react-hooks

我正在设计一个钩子(Hook),仅当钩子(Hook)依赖项发生变化时才获取数据。 它按预期工作但我收到了 linter 警告:

React Hook useEffect was passed a dependency list that is not an array literal. This means we can't statically verify whether you've passed the correct dependencies.

React Hook useEffect has missing dependencies: 'data', 'errorHandler', 'route', and 'successHandler'. Either include them or remove the dependency array. If 'successHandler' changes too often, find the parent component that defines it and wrap that definition in useCallback. 

据我所知,我不希望我的依赖项中有所有这些变量,因为我不想在这些变化时触发这个钩子(Hook),我只想在我传递的依赖项发生变化时触发它。

问题: 我如何以符合 hook linter 标准的方式设计 useFetch() hook(如果我的设计模式不符合标准,请详细说明应该如何最好地完成)。

我的 useFetch() 钩子(Hook)

function useFetch(
    {
        route,
        data = {},
        successHandler,
        errorHandler,
    },
    dependencies = []) {
    const [loading, setLoading] = useState(true);
    useEffect(() => {
        setLoading(true);
        postJson({route}, data)
            .then(
                res => {
                    if(isFunction(successHandler)) successHandler(res);
                },
                ({responseJSON: err}) => {
                    if(isFunction(errorHandler)) {
                        errorHandler(err);
                    } else {
                        notify({text: err.message || messages.saveFailed(), cssClass: 'error'});
                    }
                }
            )
            .finally(() => {
                setLoading(false);
            });
    }, dependencies);
    return loading;
}

组件使用 useFetch()

function MyComponent({data, selectedReviewId, setField}) {
    const loading = useFetch({
        route: 'foo.fetchData',
        data: {crrType, clientId, programId, userId},
        successHandler: d => setField([], d) // setField() will set data with the value fetched in useFetch() 
    }, [selectedReviewId]);

    return loading ? <SpinnerComponent/> : <div>{data.foo}</div>;
}

最佳答案

您已将依赖项作为数组传递,但在接收端,它本质上是指向数组的单个变量。 useEffect() 的 Lint 规则要求您在方括号中传递依赖项,就像在以下代码中所做的那样。

现在是一些技术性的东西。记住是什么产生了警告。它是在语法上检查代码的 lint。它不涉及语义。从语义上讲,您的依赖项列表是正确的,因为您传递的是数组,但从语法上讲,它不是作为数组传递的,即它是一个未在方括号中传递的变量(如 [dependencies])(这是 lint 正在寻找的东西)。所以为了满足lint,你应该这样写:

useEffect(
  () => { // implementation of function },
  [dependencies]
);

此外,当您发送依赖项数组时,您还可以使用展开运算符,如下所示:

useEffect(
  () => { // implementation of function },
  [...dependencies]
);

这将通过 Babel 转译器在数组运算符中展开数组元素。 Lint 也将保持安静。

关于javascript - 设计 React Hooks 防止 react-hooks/exhaustive-deps 警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57983717/

相关文章:

javascript - Jest.fn() 在 React 单元测试中不起作用

scala - 状态 monad 的 future

c++ - 如何使 C++ 算法融合?

javascript - 用户偏好的多选项卡问题

javascript - 在 div 背景加载 jQuery 后显示内容

javascript - 使用 jQuery 从 json 获取值,而不使用 foreach 循环

haskell - 列表理解中的表达式是否被冗余评估?

javascript - Charts.js 动态报价

javascript - 如何在不使用 `this` 的情况下获得重构生命周期的 Prop ?

javascript - React 中未定义上下文值