【问题标题】:useEffect exhaustive-deps rule is confusinguseEffect 详尽-deps 规则令人困惑
【发布时间】:2022-01-07 03:02:48
【问题描述】:

我在 stackoverflow 上发现了一些与此相关的问题,但没有什么能满足我在使用 useEffect 时经常遇到的用例。假设我有一些这样的代码:

const ApiViewer = (props) => {
    const [result, setResult] = useState('')

    useEffect(async () => {
        setResult(await callApi(props.valueThatWillChangeButIOnlyCareAboutItsInitialValue))
    }, [])

    return <div>{result}</div>
} 

exhaustive-deps 规则将抛出,要求我将 props.valueThatWillChangeButIOnlyCareAboutItsInitialValue 放入依赖数组中。我不想这样做,因为我只想要初始值。我可能会在某处单独使用该道具。

我也想不出另一种写法。

我也有其他人似乎有的问题,即使用我知道永远不会改变的功能/等。我不想将它们添加到这个数组中,看起来很愚蠢。

Dan Abramov 说通常禁用它是一个错误,以后会严重影响您。多年来我一直以这种方式使用它,在新项目中开始出现这条规则之前,我没有发现任何问题。

我使用 React 完全错了吗?

编辑:我已经更彻底地阅读了this 线程,并得出结论认为 Dan Abramov 真的很关心程序员,因为他希望他们关注have a job for life!我现在正在从我的项目中删除此规则。

【问题讨论】:

  • “我也有其他人似乎有的问题,即使用我知道永远不会改变的函数/等。我不想将它们添加到这个数组中,看起来很愚蠢。”您可以将“不更改”的函数移出每个渲染周期重新声明它们的范围您可以简单地记住它们并将它们添加到依赖项数组中无论如何,因为它们现在将成为稳定的参考。不要禁用 React hooks linting 规则,它可能弊大于利,而不是仅仅为你想忽略的那些添加 // eslint-disable-next-line react-hooks/exhaustive-deps 评论。
  • This comment 来自您链接的线程是最好的,恕我直言。它提到了我之前遇到的一个问题。您从/thing/1 导航到/thing/2,并且ThingDashboard 组件用于两条路线。由于 DOM 没有进行有意义的更改,因此不会创建该组件的新实例,但之前渲染中的实例现在具有不同的 props 或上下文值。任何“挂载”运行的东西此时都不会运行,这可能是一个大而令人困惑的问题。

标签: reactjs react-hooks eslint


【解决方案1】:

别担心,你做对了!详尽的 dep 只是 eslint 发出的警告,仅仅因为你收到了警告并不意味着你做错了。如果您的代码要求仅在组件的初始加载时运行某些内容,那么您的做法是完全正确的。

虽然我建议您不要完全删除此规则,而只是在必要时禁止它们。

编辑:我说不完全禁用该规则的原因是,其他钩子,如 useCallbackuseMemo 也基于依赖列表工作。如果你没有为这些钩子添加你的依赖列表,它可能会完全适得其反。

有警告总是好的,因为你不是唯一一个要从事项目的人,这也可以帮助你明天雇用的新初级开发人员。

【讨论】:

  • 感谢您的验证,但我不想让 eslint 覆盖 80% 的 useEffect 函数。
  • 嗨@DaraJava,我已经编辑了我的答案:)
【解决方案2】:

如果您想忽略对给定道具的更新,那么您可以使用useRef 来澄清这一点。当引用 useEffect 中的 ref 时,您不会收到任何警告,因为从 useRef 返回的基础对象永远不会改变。使用 initial 前缀或类似的前缀也可以让下一个开发人员明白这一点。

const ApiViewer = (props) => {
    const [result, setResult] = useState('')
    const initialValueThatWillChangeRef = useRef(props.valueThatWillChange);

    useEffect(async () => {
        setResult(await callApi(initialValueThatWillChangeRef.current))
    }, [])

    return <div>{result}</div>
} 

您当然可以通过忽略详尽的 deps 规则来构建一切都按预期工作的示例,但它会一直工作直到它不起作用。如果您说服自己该规则不是规则而是建议,那么您最终会遇到一个微妙的案例,该案例会因难以调试的原因而中断。

将详尽的 deps 视为真正的规则,这将确保组件按预期更新。

【讨论】:

    猜你喜欢
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 2022-01-21
    • 2022-01-17
    • 2020-12-07
    • 1970-01-01
    • 2018-02-26
    相关资源
    最近更新 更多