React生命周期方法理解

62

我是React.js的新手,正在努力理解React生命周期方法中的一些方法。

到目前为止,有一些让我困惑的东西:

1)

据我所知,componentWillUpdatecomponentWillReceiveProps之间的区别在于当父组件更改props时,componentWillReceiveProps将被调用,我们可以使用setState(在componentWillReceiveProps内设置此子级的setState)。

例如:react-table-sorter-demo

var App = React.createClass({
  getInitialState: function() {
    return {source: {limit: "200", source: "source1"}};
  },
  handleSourceChange: function(source) {
    this.setState({source: source});
  },
  render: function() {
    return (
      <div>
        <DataSourceSelectors onSourceChange={this.handleSourceChange} source={this.state.source} />
        <TableSorter dataSource={urlForDataSource(this.state.source)} config={CONFIG} headerRepeat="5" />
      </div>
    );
  }
});

在TableSorter中,我们有:

componentWillReceiveProps: function(nextProps) {
    // Load new data when the dataSource property changes.
    if (nextProps.dataSource != this.props.dataSource) {
      this.loadData(nextProps.dataSource);
    }
  }

当我们改变this.state.source时,我们期望TableSorter中的componentWillReceiveProps被调用。

然而,在这种情况下我不太明白如何使用componentWillUpdatecomponentWillUpdate的定义是:

componentWillUpdate(object nextProps, object nextState)

怎样将父组件的nextState传递给子组件?或者我理解错了,是从父元素中传递的nextState吗?

2) componentWillMount方法让我感到困惑,因为在官方文档中,它说:

  

在初始渲染之前,在客户端和服务器上都会被调用一次。

在这种情况下,如果我在此方法中使用setState,则它将覆盖getInitialState,因为它仅在最初被调用一次。在这种情况下,设置getInitialState方法中的参数的原因是什么。在这个特定的例子中,我们有:

  getInitialState: function() {
    return {
      items: this.props.initialItems || [],
      sort: this.props.config.sort || { column: "", order: "" },
      columns: this.props.config.columns
    };
  },
  componentWillMount: function() {
    this.loadData(this.props.dataSource);
  },
  loadData: function(dataSource) {
    if (!dataSource) return;

    $.get(dataSource).done(function(data) {
      console.log("Received data");
     this.setState({items: data});
     }.bind(this)).fail(function(error, a, b) {
      console.log("Error loading JSON");
     });
  },

项目将被首先覆盖,为什么我们仍然需要在getInitialState方法中使用items: this.props.initialItems || []

希望您可以理解我的解释,如果有任何提示,请告诉我。


1
nextState 不会从父组件传递到子组件。 - Colin Ramsay
6个回答

70

1) 在React的更新生命周期中,componentWillReceivePropscomponentWillUpdate之前被调用。你说得对,componentWillReceiveProps允许你调用setState。另一方面,componentWillUpdate是一个回调函数,在需要响应状态更改时使用。

Props和State之间的根本区别在于State是组件私有的。这就是为什么父组件或其他任何人都不能操作该组件的状态(例如调用setState)。因此,父子组件关系的默认工作流程如下:

  • 父组件将新的props传递给子组件
  • 子组件在'componentWillReceiveProps'中处理新的props,必要时调用setState
  • 子组件在'componentWillUpdate'中处理新的state - 但如果你的组件是有状态的,则在'componentWillReceiveProps'中处理props就足够了。

2) 你提供了一个相当好的代码示例来说明这个区别。在getInitialState中设置的默认值将用于初始渲染。从componentWillMount中调用的loadData将启动一个可能成功或失败的AJAX请求 - 而且不知道完成需要多长时间。当AJAX请求完成并使用新状态调用setState时,组件将以默认值在DOM中呈现。这就是为什么在getInitialState中提供默认状态完全有意义。

注意:我发现理解React组件生命周期文章对理解React的生命周期方法非常有帮助。


8

React组件生命周期的四个阶段:

初始化

挂载

更新

卸载

以下是React组件不同生命周期方法的快速概述。您必须充分理解生命周期方法,才能在React中高效地编写代码。

生命周期阶段方法

挂载阶段方法:

当组件实例被创建且在DOM中渲染时,该阶段开始。

1. constructor(props) - 当组件首次初始化时调用。此方法仅调用一次。
2. componentWillMount() - 当组件即将挂载时调用。
3. render() - 当组件被渲染时调用。
4. componentDidMount() - 当组件完成挂载时调用。

更新阶段方法:

当组件的属性(也称为props)或状态更改时,该阶段开始。

1. componentWillReceiveProps(nextProps) - 当组件已更新并接收到新props时调用。
2. shouldComponentUpdate(nextProps, nextState) - 在接收到props并即将更新时调用。如果此方法返回false,则不会执行componentWillUpdate()、render()和componentDidUpdate()。
3. componentWillUpdate(nextProps, nextState) - 当组件即将被更新时调用。
4. render() - 当组件重新渲染时调用。
5. componentDidUpdate(prevProps, prevState) - 当组件完成更新时调用。

卸载阶段方法:

当组件从DOM中删除时,该阶段开始。

1. componentWillUnmount() - 组件卸载之前立即调用。

参考: https://hackernoon.com/reactjs-component-lifecycle-methods-a-deep-dive-38275d9d13c0


尽管基于类的组件被Hooks取代了,但对于刚开始学习的人来说,了解这些仍然是有用的知识。此外,许多现有项目都使用Class组件编写,要处理这些项目,上述内容是必须掌握的。 - Aftab22

5

3

Yevgen 上面已经提到了。 - ridoansaleh
感谢您在这么长时间之后通知我。 - Himanshu Teotia

0

React中的源代码生命周期方法

您可以创建组件并运行您的项目。在浏览器中检查控制台以获取呈现日志。

import React, { Component } from 'react'

class LifecycleA extends Component {
    constructor(props) {
        super(props)

        this.state = {
            name: 'triadmoko'
        }
        console.log('lifecycle A constructor');
    }

    static getDerivedStateFromProps(props, state) {
        console.log('lifecycle A getDerivedStateFromProps');
        return null
    }
    componentDidMount = () => {
        console.log('lifecylce A componentDidMount');
    }
    render() {
        console.log('lifecycle A render');

        return (
            <div>LifecycleA</div>
        )
    }
}

export default LifecycleA

0
组件生命周期方法是一种我们可以在基于类的组件内部选择性定义的函数。如果我们决定实现这些方法,React 将在组件的生命周期某些时刻自动调用它们。
组件将被创建并显示在 DOM 或浏览器中,我们可以执行像 this.setState() 这样的操作,该操作会导致组件重新渲染,并且理论上,在某个时间点组件将从 DOM 中删除,不再在屏幕上显示其内容。
整个事件序列被称为组件的生命周期。
这些生命周期方法在生命周期的非常不同的时间被调用。
有一个 constructor(props) 函数,这是一个我们可以选择定义的函数,如果我们这样做了,当组件的新实例被创建时,它将自动调用。
还有一个 render() 方法,它不是可选的,我们必须定义它。 render() 方法是一个生命周期函数,它在组件的生命周期某个时间点被调用。
我们从调用 constructor(props) 开始,然后将调用 render() 方法,返回一些 JSX,并且内容变得可见在屏幕上。

然后,在不同的时间点调用另一系列的生命周期方法。

首先,在组件出现在浏览器屏幕上之后,将会调用一个名为componentDidMount()的生命周期方法。这意味着如果我们在类内部定义一个函数,在constructor(props)之外,在render()方法的上方,我们可以这样定义一个名为componentDidMount()的方法:

componentDidMount() {

}

render() {

}

这个函数将在组件第一次渲染到屏幕上时自动调用一次。我们可以在其中放置代码以进行设置或执行一些初始数据加载或各种操作,这些操作可能是在组件首次显示时想要执行一次的。

在调用该方法后,组件将等待更新。更新将以 this.setState() 的形式出现。

完成后,组件将更新或重新呈现自身,这将调用另一个生命周期方法,称为 componentDidUpdate()。如果我们定义了该函数,每当组件更新自身时,它都会自动调用。

组件将等待另一个更新和 componentDidUpdate() 再次或多次。

在某些时候,我们可能希望停止 componentDidUpdate() 组件,这就是我们实现 componentWillUnmount() 的地方,这是我们想要在清理组件时调用的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接