【问题标题】:when to use componentWillMount instead of componentDidMount何时使用 componentWillMount 而不是 componentDidMount
【发布时间】:2018-01-23 10:59:21
【问题描述】:

我只是找不到这两种生命周期方法的实际使用示例。我在react中写了一段时间,但是componentDidMount只是完成了工作,这意味着调用fetch async data,但是我没有看到willMount的意义,有什么线索吗?

【问题讨论】:

  • 我不使用 react 但我在其他框架中使用了类似的生命周期助手:通过 AJAX 获取一些需要的数据,显示/隐藏页面上的其他元素,确保这是唯一的实例在页面上,对道具等做一些计算

标签: javascript reactjs


【解决方案1】:

比较两者:

componentWillMount 在初始渲染之前运行。但不建议在此方法中进行任何订阅和状态设置。如果你想在渲染之前做一些事情,你可以使用组件的构造函数。

componentWillMount() 在安装发生之前立即调用。它
render() 之前调用,因此同步调用setState()
在这种方法中不会触发额外的渲染。一般来说,我们
建议改用 constructor()。避免引入任何
此方法中的副作用或订阅。对于这些用例,请使用
componentDidMount() 代替。

可能的用例:

  • 设置组件的初始状态(但您可以使用构造函数)
  • 在服务器端渲染中运行服务器端代码以获取初始状态
  • 获取数据并设置初始状态

componentDidMount 但是在初始渲染之后运行并标记组件最终完成安装 DOM 的时间。因此,您可以使用它来设置订阅和侦听器,甚至可以将数据获取到 setState。

componentDidMount() 在组件被调用后立即调用
安装。需要 DOM 节点的初始化应该放在这里。如果你
需要从远程端点加载数据,这是一个很好的地方
实例化网络请求。这个方法是设置的好地方
任何订阅。如果您这样做,请不要忘记在
componentWillUnmount() 中取消订阅。在这个方法中调用setState()会触发
额外的渲染,但它会在浏览器更新之前发生
屏幕。这保证即使 render() 将被调用
在这种情况下两次,用户将看不到中间状态。使用
谨慎使用此模式,因为它通常会导致性能问题。
但是,对于模态和工具提示等情况,当
你需要在渲染依赖的东西之前测量一个 DOM 节点
关于它的大小或位置。

可能的用例:

  • 设置事件侦听器,因为组件已安装
  • 获取数据并设置状态
  • 设置依赖 DOM 的第三方库

大不同:在服务器端渲染中,只有componentWillMount 在服务器端运行。因此,如果您曾经使用过 SSR,请确保 componentDidMount 中没有任何服务器端代码

目前您可以(您决定是否应该)同时使用这两者来设置初始状态。一般来说,我看到大多数人为此使用 componentDidMount,但需求会发生变化,您可能会发现一些使用 componentWillMount 的用例。

然而,有人谈论过弃用生命周期方法。 here

【讨论】:

  • ...的实际使用示例 OP 正在寻找一些需要这些功能的用例
  • 当您可以在 DidMount 中获取数据时,为什么还需要在 WillMount 中获取数据?
  • 但这是一个很好的答案,至少现在我知道SSR中使用了WillMount。
  • @XieXieFang 你不需要,但你可以。将来 React 将添加异步渲染,WillMount 将不再像以前那样工作。所以是的,总是使用 didMount
  • 为了补充使用componentDidMount()的原因,必须注意在构造函数或componentWillMount()中使用异步fetch()可能会在初始渲染已经发生后解决,这是不可取的,并且在某种程度上违背了目的。此外,人们通常希望在获取数据时渲染加载动画,在这种情况下,无论如何都需要先渲染组件。
【解决方案2】:

componentWillMount 和 componentDidMount 的区别在于它们被调用的时间。 componentWillMount 在渲染之前调用,这意味着在 componentWillMount 中同步设置状态不会导致额外的渲染调用,而 componentDidMount 在渲染之后调用,因此此方法中的任何状态更改都会导致额外的渲染调用。

对于任何异步调用,使用 componentDidMount 代替 componentWillMount。

【讨论】:

  • ...的实际使用示例 OP 正在寻找一些需要这些功能的用例
  • 我知道 willMount 和 DidMount 的确切区别,只是在现实生活中我仍然找不到任何实际区别。
【解决方案3】:

更新反应 17

componentWillMount 自 React 16.3(2018 年 3 月)起已弃用。在 React 17 之前,这种方法将继续有效。取而代之的是,您可以在类组件中使用 构造函数componentDidMount

From the official docs:

UNSAFE_componentWillMount() 以前被命名为 componentWillMount。该名称将继续使用到版本 17。使用 rename-unsafe-lifecycles 代码模块自动更新您的组件。

【讨论】:

    【解决方案4】:

    我经常使用 componentWillMount。就我而言,我将它用作“构造函数”而不是真正的构造函数。

    componentWillMount() {
        this.setState({
            myKey: myValue
        });
    }
    

    而不是

    constructor(props) {
        super(props);
    
        this.state = {
            myKey: myValue
        };
    }
    

    您节省了几行代码并且不必调用超级函数。有了它,您也可以发送您的 ajax 请求 - 而不是使用两个函数(构造函数和 componentDidMount)。

    ComponentWillMount 在生命周期中比 componentDidMount 更早地被调用,因此这通常是放置必须很快完成的事情的正确位置。

    这不是一个强有力的论点,但足以解释为什么 componentWillMount 完全有用。

    【讨论】:

    • ComponentWillMount is called earlier in the lifecycle than componentDidMount, , so this is often the right place to put things which have to be done very soon.你能给我举一个实际的例子吗?
    【解决方案5】:

    ComponentWillMount 可用于初始化一些变量、对象或 API 库。例如,我以前使用 AJAX 调用从 API 获取用户的位置。通过这个调用,我得到了位置,并保存了要在应用程序中渲染时使用的位置。

    ComponentDidMount 非常适合订阅和更改 DOM,因为此时 DOM 应该准备好了。有一个反模式说您必须避免在 ComponentDidMount 中使用 AJAX 调用和一组数据,但我认为这取决于您的解决方案以及您如何处理渲染函数。

    【讨论】:

    • 文档明确说使用 componentDidMount 而不是 componentWillMount 进行 ajax 调用:reactjs.org/docs/react-component.html#componentdidmount
    • 是的,但是当文档说这是因为通常所有 AJAX 都会获取将呈现的数据。例如,在这种情况下,我只需要知道用户的位置,设置将用于子组件的默认信息。
    猜你喜欢
    • 2015-09-03
    • 1970-01-01
    • 2015-01-24
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 2019-05-30
    • 1970-01-01
    相关资源
    最近更新 更多