1.version16.3以前
1.第一个是组件初始化(initialization)阶段
constructor
import React, { Component } from 'react';
class Test extends Component {
constructor(props) {
super(props);
}
}
//代码中类的构造方法( constructor() ),Test类继承了react Component这个基类,
//也就继承这个react的基类,才能有render(),生命周期等方法.
//super(props)用来调用基类的构造方法( constructor() ), 也将父组件的props注入给子组件,供子组件读取(组件中props只读不可变,state可变)。
2.组件挂载
componentWillMount,render,componentDidMount
3.组件的更新(update)阶段
componentWillReceiveProps,shouldComponentUpdate,componentWillUpdate,render,componentDidUpdate
在此阶段前需要先明确下react组件更新机制。setState引起的state更新或父组件重新render引起的props更新,更新后的state和props相对之前无论是否有变化,都将引起子组件的重新render。
4.卸载阶段
componentWillUnmount
16.3以后
1.弃用componentWillMount
。
因为有人滥用
componentWillMount
,componentWillMount
里发起AJAX
,不管多快得到结果也赶不上首次render
,禁止不能用比劝导开发者不要这样用的效果更好
2.componentWillMount,componentWillReceiveProps,componentWillUpdate
都被getDerivedStateFromProps
替代
3.引入getDerivedStateFromProps,getSnapshotBeforeUpdate
getDerivedStateFromProps
static getDerivedStateFromProps(props, state) 在组件创建时和更新时的render方法之前调用,它应该返回一个对象来更新状态,或者返回null来不更新任何内容。getDerivedStateFromProps无论是Mounting还是Updating,也无论是因为什么引起的Updating,全部都会被调用
getSnapshotBeforeUpdate
getSnapshotBeforeUpdate() 被调用于render之后,可以读取但无法使用DOM的时候。它使您的组件可以在可能更改之前从DOM捕获一些信息(例如滚动位置)。此生命周期返回的任何值都将作为参数传递给componentDidUpdate()。
官网给的例子:
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
//我们是否要添加新的 items 到列表?
// 捕捉滚动位置,以便我们可以稍后调整滚动.
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
//如果我们有snapshot值, 我们已经添加了 新的items.
// 调整滚动以至于这些新的items 不会将旧items推出视图。
// (这边的snapshot是 getSnapshotBeforeUpdate方法的返回值)
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.listRef}>{/* ...contents... */}</div>
);
}
}
举一个例子
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class App extends React.Component {
constructor() {
super();
console.log("constructor");
this.state = {
text: 123
};
}
static Xxx() {
console.log(123123);
}
componentWillMount() {
console.log("willMount");
}
shouldComponentUpdate() {
console.log("shouldUpdate");
return true;
}
componentWillUpdate() {
console.log("willUpdate");
}
componentDidUpdate() {
console.log("DidUpdate");
}
componentDidMount() {
console.log("DidMount");
this.setState({ text: 456 });
}
render() {
console.log("render");
return (
<div>
<B text={this.state.text} />
</div>
);
}
}
class B extends React.Component {
componentWillReceiveProps() {
console.log("B", "Receive");
}
shouldComponentUpdate() {
console.log("B", "shouldUpdate");
return true;
}
componentWillUpdate() {
console.log("B", "willUpdate");
}
componentDidUpdate() {
console.log("B", "didUpdate");
}
render() {
console.log("B", "render");
return <div>{this.props.text}</div>;
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
打印顺序: