React: 为什么 useEffect 的默认行为是在每次渲染时运行?

创建于 2019-11-26  ·  3评论  ·  资料来源: facebook/react

您要请求功能还是报告错误
关于useEffect API 设计问题

目前的行为是什么?
目前useEffect在每次渲染上运行。 当您忘记传递第二个参数时,这种默认行为在处理 HTTP 请求等情况下可能很危险。 这似乎是一个常见的错误,特别是对于像我这样的新人。 我想不出很多(任何)模式你想在每次渲染时运行useEffect 。 不默认运行一次的原因是什么?

Question

所有3条评论

通过 API 设计:

useEffect(
    () => {
        // do something
    },
    [/* dependency list */]
);

useEffect只会在依赖列表改变时运行,空数组[]表示没有依赖(即只会运行一次)。 对我来说,未定义的依赖项列表意味着每次渲染都运行由useEffect包装的函数。

我想不出很多(任何)模式你想在每次渲染时运行useEffect 。 不默认运行一次的原因是什么?

假设您对 React 非常陌生,并且您想在useState变量发生变化时做一些事情(例如将新值 POST 到服务器)。

  • 使用当前行为,您将多次发布相同的值,但绝不会错过发布更改后的值。
  • 根据您建议的行为,只有初始值/第一次更改会被发布,进一步的更改不会触发useEffect回调。

我认为依赖项列表旨在更多地进行性能优化/帮助代码简化。

当前的 API 允许您在以下行为之间做出决定:

  • 每次运行效果。 这模仿了旧类componentDidMount + componentDidUpdate行为。
  • 只运行一次效果。 这模仿了旧的componentDidMount行为。
  • 仅在依赖项更改时运行效果。 这是一种新方法,尽管您可以(并且经常这样做)通过类组件 API 中的组件this.propsprevProps实现相同的功能。

您描述的“默认”行为(当您没有明确指定依赖项时)通常是最安全的,因为它可以防止在闭包中使用陈旧的值

在未来,希望我们能提供某种类型的编译器来帮助自动化很多。 同时,我们提供了一个官方的 ESLint 插件来帮助

此页面是否有帮助?
0 / 5 - 0 等级