简体   繁体   English

设计React Hooks可以防止React-Hooks / Exhaustive-deps警告

[英]Designing React Hooks prevent react-hooks/exhaustive-deps warning

I am designing a hook to fetch data only when the hooks dependencies change. 我正在设计一个挂钩,仅在挂钩依赖项更改时才获取数据。 It works as expected but I receive the linter warnings: 它可以按预期工作,但是我收到了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.

and

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. 

As far as I am aware I do not want all these vars in my dependencies as I don't want to fire this hook when these change, I only want to fire it when the dependencies I pass change. 据我所知,我不希望所有这些var都存在于我的依赖项中,因为我不想在这些更改时触发此钩子,我只想在我通过的依赖项更改时触发它。

Question: How can I design useFetch() hook in a way that coincides with the hooks linter standards (if my design pattern is not up to par, please elaborate on how best this should be accomplished). 问题:如何以与钩子linter标准一致的方式设计useFetch()钩子(如果我的设计模式不符合标准,请详细说明应如何最好地实现)。

My useFetch() hook 我的useFetch()挂钩

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;
}

Component using useFetch() 使用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>;
}

You have passed dependency as array but on the receiving end, it's essentially a single variable pointing to an array. 您已经将依赖项作为数组传递了,但是在接收端,它实质上是指向数组的单个变量。 Lint rule of useEffect() requires that you pass dependencies in square brackets like done in following code. useEffect()useEffect()规则要求您像下面的代码中那样在方括号中传递依赖项。

Now some technical stuff. 现在介绍一些技术资料。 Remember what's generating the warning. 记住是什么产生警告。 It's the lint which checks code syntactically. 皮棉语法地检查代码。 It doesn't go into semantics. 它没有涉及语义。 Semantically, your list of dependencies is correct, as you are passing an array but syntactically, it's not being passed as an array ie it's a single variable not passed in square brackets (like this [dependencies] ) (which is something lint is looking for). 从语义上讲,您的依赖项列表是正确的,因为您正在传递数组,但是从语法上讲,它不是作为数组传递的,即它是一个未在方括号中传递的单个变量(例如[dependencies] )(这是lint正在寻找的东西) )。 So in order to satisfy lint, you should write: 因此,为了满足皮棉的要求,您应该编写:

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

Further, as you are sending an array of dependencies, you can also use spread operator, like this: 此外,在发送依赖项数组时,还可以使用传播运算符,如下所示:

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

This will spread the array elements inside array operator by Babel transpiler. 这将通过Babel Transpiler将数组元素散布到数组运算符中。 Lint will also remain quiet. 皮棉也将保持安静。

The eslint warning is right - you should include those as dependencies. eslint警告是正确的-您应将其包括为依赖项。 For example, in your MyComponent if data changes, and it is not in your dependency list, your useEffect hook will be calling fetch will outdated data . 例如,在MyComponent如果data发生更改,并且不在依赖列表中,则useEffect挂钩将调用fetch将过期的data

Same applies to others - it's advised to add those to your dependencies list. 同样适用于其他人-建议将它们添加到您的依赖项列表中。

For the first error, it is probably ok - even though not ideal. 对于第一个错误,这可能没问题-即使不理想。 You have a dynamic dependencies list - eslint can't be sure if you have all the required stuff in there. 您有一个动态的依赖项列表eslint不确定其中是否包含所有必需的内容。

Your solution is probably going to work - but it is very fragile. 您的解决方案可能会起作用-但它非常脆弱。 If your dependencies happen to change (eg additional elements, or removed elements) 如果您的dependencies发生更改(例如,其他元素或已删除的元素)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 反应 useEffect 带有警告的钩子 react-hooks/exhaustive-deps - React useEffect hook with warning react-hooks/exhaustive-deps 带有自定义 IntersectionObserver 钩子的 react-hooks/exhaustive-deps 警告 - react-hooks/exhaustive-deps warning with custom IntersectionObserver hook useEffect 和 &#39;react-hooks/exhaustive-deps&#39; linting - useEffect and 'react-hooks/exhaustive-deps' linting 未找到规则“re​​act-hooks/exhaustive-deps”的定义 - Definition for rule 'react-hooks/exhaustive-deps' was not found react-hooks/exhaustive-deps 导致依赖警告,修复挂起代码 - react-hooks/exhaustive-deps causing dependency warning, fix hangs code React Hooks react-hooks/exhaustive-deps eslint 规则似乎过于敏感 - React Hooks react-hooks/exhaustive-deps eslint rule seems overly sensitive 如何在React中使用钩子实现componentDidMount以使其符合EsLint规则“ react-hooks / exhaustive-deps”:“ warn”? - How to implement componentDidMount with hooks in React to be in line with the EsLint rule “react-hooks/exhaustive-deps”: “warn”? 我如何正确使用 useEffect 进行异步获取调用和反应? 反应钩子/详尽的deps - How do i properly use useEffect for a async fetch call with react? react-hooks/exhaustive-deps 如何解决`react-hooks/exhaustive-deps`的`React Hook useEffect缺少依赖`? - How to solve `React Hook useEffect has a missing dependency` of `react-hooks/exhaustive-deps`? React挂钩:如何使用react-hooks / exhaustive-deps规则在没有无限循环的情况下读取和更新挂钩中的状态 - React hooks: How to read & update state in hooks without infinite loops with react-hooks/exhaustive-deps rule
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM