create-react-app 建议:强制要求钩子依赖的不可变性,而不是详尽的依赖项,

3vpjnl9f  于 2个月前  发布在  React
关注(0)|答案(2)|浏览(51)

你好,关于CRA的react-hooks/exhaustive-depslint规则在issue #6880中的正反讨论,我们可以安全地假设,详尽的依赖规则会导致一些不必要的繁琐工作,甚至引入不期望的副作用,而开发者可能并不打算这样做。
为了说明我的意思:如果我有一个普通的功能组件,其中在useEffect钩子中有getTodos() API调用,目前详尽的依赖规则要求我将getTodos()添加到依赖数组中。然而,作为开发者,我从未打算改变这个函数,因此在整个组件的执行过程中它应该是不可变的。此外,如果它真的发生了变化,那将是一个bug,这将使将其作为依赖项与我最初的目标相矛盾,即只在每次挂载时运行一次hook。在这种情况下,正确的行为应该是抛出一个错误,而不是进行非常奇怪的useEffect钩子的重新计算。而且,尽管需要将所有可以想象得到的东西添加到依赖数组中,但这仍然令人讨厌的开销。
我希望我的论证是有道理的,原始线程的参与者,包括@gaearon,可以证明这是一个值得辩论的问题。
这个问题的解决方案是强制props/变量的不可变性,这是另一个完全不同的问题,我不知道如何实现或用linter检查这样的东西。也许这个问题只能通过向React添加额外的不可变功能或错误检查来解决,这似乎有点牵强。
在此期间,我会尝试找到自己的方法来处理这个问题。也许我会禁用这个规则,相信我只记得在组件生命周期中应该和可以改变的变量上添加依赖项。但是为了保持理智,我不会浪费时间在将所有可能的变量添加到依赖数组上,因为它们本来就不应该在一开始就改变。如果React能够在这些值不必要地改变时抛出错误,那已经是一个很大的改进了。

uujelgoq

uujelgoq1#

我遇到了类似的问题,我可以简单地将其拆分。
当使用 useState 时,CRA 正确地识别出返回数组中的第二个元素(设置器)不需要包含在任何依赖数组中。请参考以下内容:

import React, {useCallback, useState} from 'react';

export default () => {
    const [counter, setCounter] = useState(0);

    const onButtonClick = useCallback(() => {
        setCounter(oldCounterValue => oldCounterValue + 1);
    }, []);

    return <>
        <span>{counter}</span>
        <span><button type="button" onClick={onButtonClick}>Increment</button></span>
    </>;
}

上述代码没有生成警告。然而,如果创建一个简单的 Package 器 useState 的新钩子,就会生成警告。请参考以下内容:

import React, {useCallback, useState} from 'react';

const useCounter = initialValue => {
    const [counter, setCounter] = useState(initialValue);

    const incrementCounter = useCallback(() => {
        setCounter(oldCounterValue => oldCounterValue + 1);
    }, []);

    return [counter, incrementCounter];
}

export default () => {
    const [counter, incrementCounter] = useCounter(0);

    const onButtonClick = useCallback(() => {
        incrementCounter();
    }, []);

    return <>
        <span>{counter}</span>
        <span><button type="button" onClick={onButtonClick}>Increment</button></span>
    </>;
}

这段代码生成了警告 Line 18:8: React Hook useCallback has a missing dependency: 'incrementCounter'. Either include it or remove the dependency array react-hooks/exhaustive-deps
通过手动分析第二段代码,很明显 useCounter 钩子返回的第二个数组项与 useState 钩子返回的设置器一样是不可变的。我们是否可以告诉 linter 在这种情况下不生成警告?

55ooxyrt

55ooxyrt2#

它还警告任何第三方库。比如你使用Redux并在useEffect中使用dispatch或Actions。实际上任何东西,它说需要放在依赖数组中。这并不是什么大问题,但它会导致开发者在不需要的情况下将所有内容添加到依赖数组中,因为它们永远不会改变。

相关问题