【问题标题】:Why componentWillMount should not be used?为什么不应该使用 componentWillMount?
【发布时间】:2018-02-13 02:12:31
【问题描述】:

在 componentWillMount 生命周期方法中触发服务器调用以获取数据是一种不好的做法吗?

以及为什么使用 componentDidMount 更好。

【问题讨论】:

    标签: javascript reactjs redux react-redux


    【解决方案1】:

    更新: componentWillMount 很快就会成为deprecated


    引用@Dan Abramov

    未来的 React 版本中,我们预计 componentWillMount 在某些情况下会触发不止一次,因此您应该使用 componentDidMount 来处理网络请求。

    阅读更多here

    【讨论】:

    • 这是我以前读到的,但从来没有合理的理由说明为什么它会被多次调用。
    • 这是一个仅链接的答案,不解释问题的“为什么”上下文。任何其他回答都更好地回答了这个问题,所以这不应该是公认的答案。
    • 对不起,如果我的问题很愚蠢。如果我在componentWillMount中取数据,即使不破坏第一次渲染的组件,`componentWillMount`中的取数据函数是否会比取数据componentDidMount函数调用早一点,导致Do we get数据快一点?
    【解决方案2】:

    按照我的理解,最大的原因之一与为开发人员设置正确的期望阅读代码有关。

    如果我们使用componentWillMount,很容易认为获取有时间发生,然后组件“确实”挂载,然后第一次渲染将会发生。但事实并非如此。如果我们进行异步调用(如使用 Promises 的 API 调用),组件将实际运行 render,然后 fetch 可以返回并设置组件状态(或更改 Redux 状态,或其他任何方式)。

    如果我们改为使用componentDidMount,那么很明显该组件将在您取回任何数据之前至少呈现一次(因为该组件已经进行挂载)。因此,通过扩展,很明显我们必须以某种方式处理初始状态,以便组件不会在第一次(“空”)渲染时中断。

    【讨论】:

      【解决方案3】:

      componentDidMount 是调用获取数据的最佳位置,原因有两个:

      1. 使用componentDidMount 可以清楚地表明,在初始渲染之前不会加载数据。您需要正确设置初始状态,以免获得导致错误的undefined 状态。

      2. 如果您需要在服务器上呈现您的应用程序,componentWillMount 将被调用两次(在服务器上和客户端上),这可能不是您想要的。将数据加载代码放入componentDidMount 将确保仅从客户端获取数据。一般来说,你不应该给componentWillMount添加副作用。

      【讨论】:

      • 我想在组件出现之前显示加载器
      【解决方案4】:

      更新 - 2018 年 5 月
      在名为 async rendering 的工作进程中有一个新的 react 功能。
      从 react v16.3.2 开始,这些方法使用起来并不“安全”:

      • 组件WillMount
      • componentWillReceiveProps
      • componentWillUpdate

      您可以在docs 中阅读更多相关信息。


      作为一般规则 don't use componentWillMount (如果您使用 es6 class 语法)。请改用constructor 方法。
      这种生命周期方法适用于同步状态初始化。
      另一方面,componentDidMount 适用于异步状态操作。

      为什么
      好吧,当您在 constructor / componentWillMount 中执行异步请求时,您会在调用 render 之前执行此操作,当异步操作完成时,render 方法很可能已经完成并且没有必要设置这个阶段的“初始状态”是什么?
      我不确定这是否是您的情况,但开发人员希望在componentWillMount 中异步启动状态的大多数情况是为了避免第二次render 调用。但是你不能避免它,就像上面提到的那样,render 无论如何都会在异步操作完成之前触发。
      因此,调用异步操作的最佳时间是在调用 render 并安装组件之后(您可以安装 null 或空的 <div/>),然后获取数据,设置状态并使其重新分别渲染。

      【讨论】:

      • 正确,异步调用示例的解释为不使用 componentwillmount 提供了足够的理由。谢谢哥们:)
      • 对不起,如果我的问题很愚蠢。如果我在componentWillMount中取数据,即使不破坏第一次渲染的组件,`componentWillMount`中的取数据函数是否会比取数据componentDidMount函数调用早一点,导致Do we get数据快一点?
      • @DuyHưngAndrogyneTenor 不,因为什么时候获取数据并不重要,重要的是你什么时候可以用它做点什么。事实上,数据是在异步操作中处理的,它只会在所有同步工作完成后运行。所以我怀疑有什么区别。
      • @Sagivb.g:是的,非常感谢,所以,从构造函数到安装到渲染结束的所有过程都是同步动作,对吧?那些会在异步操作之前进入调用堆栈?
      • @DuyHưngAndrogyneTenor 所有用户的代码(不是像setState 这样的反应代码)都是同步的。所以是的,我们的代码将在异步代码之前运行完成。当然,除非我们使用异步 API,例如 setTimeout promise 等。
      【解决方案5】:

      组件挂载生命周期是

      • 构造函数()
      • componentWillMount() /UNSAFE_componentWillMount()(反应 16)
      • 渲染()
      • componentDidMount()

      ConstructorcomponentWillMount 都在负责页面渲染的 render() 调用之前调用。

      这里的状态初始化是在构造函数中完成的,并且由于异步调用而在 componentDidMount 中调用了 api。

      ComponentWillMount 在 ES6 之前的初始化状态很好,当构造函数不存在时。但是现在 ComponentWillMount 没什么用,react 团队在 react 17 之后才考虑它。

      上述之外,react 已移至 reactfiber architecture,为避免不必要的重新渲染并提高性能,react 已决定放弃 componentWillMount、componentWillReciveProps 和 componentWillUpdate 方法。

      【讨论】:

      • 它没有回答为什么 componentWillMount 不安全并且不用于数据获取。
      • 这是 React 的官方声明。他们有充分的理由引入它,现在因为 ES6 不再需要它,所以 React 团队自己声明它是不安全的。并建议使用 constructor() 而不是 componentWillMount()。
      猜你喜欢
      • 2015-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-22
      • 2014-03-25
      • 2010-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多