React 生命周期
组件的生命周期
React 中的每个组件都有一个生命周期,您可以在其三个主要阶段对其进行监控和操作。
三个阶段是:安装、更新和卸载。
安装
安装意味着将元素放入 DOM。
React 有四个内置方法,在安装组件时按此顺序调用:
constructor()
getDerivedStateFromProps()
render()
componentDidMount()
render()
方法是必需的并且总是被调用,其他是可选的,如果你定义了它们就会被调用。
constructor
constructor()
方法在其他任何事情之前被调用,当组件启动时,它是设置初始 state
和其他初始值。
constructor()
方法以 props
作为参数调用,您应该始终先调用 super(props)
,然后再调用其他任何方法,这将启动父级的构造方法并允许组件从其父级 (React.Component
) 继承方法。
示例:
constructor
方法被 React 调用,每次你创建一个组件时:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
render() {
return (
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
getDerivedStateFromProps
getDerivedStateFromProps()
方法在渲染 DOM 中的元素之前调用。
这是根据初始 props
设置 state
对象的自然位置。
它以 state
作为参数,并返回一个对 state
进行更改的对象。
下面的示例以最喜欢的颜色为 "red" 开始,但 getDerivedStateFromProps()
方法根据 favcol
属性更新最喜欢的颜色:
示例:
getDerivedStateFromProps
方法在 render 方法之前被调用:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
static getDerivedStateFromProps(props, state) {
return {favoritecolor: props.favcol };
}
render() {
return (
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
);
}
}
ReactDOM.render(<Header favcol="yellow"/>, document.getElementById('root'));
render
render()
方法是必需的,并且是实际将 HTML 输出到 DOM 的方法。
示例:
一个带有简单 render()
方法的简单组件:
class Header extends React.Component {
render() {
return (
<h1>This is the content of the Header component</h1>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
componentDidMount
componentDidMount()
方法在组件渲染后调用。
这是您运行要求组件已放置在 DOM 中的语句的地方。
示例:
起初我最喜欢的颜色是红色,但等一下,它变成了黄色:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
componentDidMount() {
setTimeout(() => {
this.setState({favoritecolor: "yellow"})
}, 1000)
}
render() {
return (
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
Updating
生命周期的下一个阶段是组件更新。
只要组件的 state
或 props
发生变化,就会更新组件。
React 有五个内置方法,当组件更新时,它们会按此顺序被调用:
getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
render()
方法是必需的并且总是会被调用,其他是可选的,如果你定义了它们就会被调用。
getDerivedStateFromProps
同样在 updates 处调用 getDerivedStateFromProps
方法。 这是组件更新时调用的第一个方法。
这仍然是根据初始 props 设置 state
对象的自然位置。
下面的示例有一个按钮,可以将喜欢的颜色更改为蓝色,但是由于调用了 getDerivedStateFromProps()
方法,该方法使用来自 favcol 属性的颜色更新状态, 最喜欢的颜色仍然呈现为黄色:
示例:
如果组件得到更新,则调用 getDerivedStateFromProps()
方法:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
static getDerivedStateFromProps(props, state) {
return {favoritecolor: props.favcol };
}
changeColor = () => {
this.setState({favoritecolor: "blue"});
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<button type="button" onClick={this.changeColor}>Change color</button>
</div>
);
}
}
ReactDOM.render(<Header favcol="yellow"/>, document.getElementById('root'));
shouldComponentUpdate
在 shouldComponentUpdate()
方法中,您可以返回一个布尔值,指定 React 是否应该继续渲染。
默认值为 true
。
下面的示例显示了当 shouldComponentUpdate()
方法返回 false
时会发生什么:
示例:
在任何更新时停止渲染组件:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
shouldComponentUpdate() {
return false;
}
changeColor = () => {
this.setState({favoritecolor: "blue"});
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<button type="button" onClick={this.changeColor}>Change color</button>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
示例:
与上面的示例相同,但这次 shouldComponentUpdate()
方法返回 true
:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
shouldComponentUpdate() {
return true;
}
changeColor = () => {
this.setState({favoritecolor: "blue"});
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<button type="button" onClick={this.changeColor}>Change color</button>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
render
render()
方法当然会在组件更新时调用,它必须将 HTML 重新渲染到 DOM,使用 新的变化。
下面的示例有一个按钮,可以将喜欢的颜色更改为蓝色:
示例:
单击按钮以更改组件的状态:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
changeColor = () => {
this.setState({favoritecolor: "blue"});
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<button type="button" onClick={this.changeColor}>Change color</button>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
getSnapshotBeforeUpdate
在 getSnapshotBeforeUpdate()
方法中,您可以访问 props
和 state
之前的更新,这意味着即使在更新之后,您也可以检查更新之前 之前 的值。
如果存在 getSnapshotBeforeUpdate()
方法,还应该包含 componentDidUpdate()
方法,否则会报错。
下面的示例可能看起来很复杂,但它所做的只是:
当组件 安装 时,它会以最喜欢的颜色 "red" 呈现。
当组件已安装时,计时器会更改状态,一秒钟后,最喜欢的颜色变为 "yellow"。
这个动作触发了更新阶段,由于这个组件有一个 getSnapshotBeforeUpdate()
方法,所以这个方法被执行,并且向空的 DIV1 元素写入一条消息。
然后执行 componentDidUpdate()
方法并在空的 DIV2 元素中写入一条消息:
示例:
使用 getSnapshotBeforeUpdate()
方法找出更新前 state
对象的样子:
class Header extends React.Component { constructor(props) { super(props); this.state = {favoritecolor: "red"};
}componentDidMount() { setTimeout(() => { this.setState({favoritecolor: "yellow"}) }, 1000)
}getSnapshotBeforeUpdate(prevProps, prevState) { document.getElementById("div1").innerHTML = "Before the update, the favorite was " + prevState.favoritecolor; } componentDidUpdate() { document.getElementById("div2").innerHTML = "The updated favorite is " + this.state.favoritecolor;
}render() { return ( <div> <h1>My Favorite Color is {this.state.favoritecolor}</h1> <div id="div1"></div> <div id="div2"></div> </div> );
}}
ReactDOM.render(<Header />, document.getElementById('root'));
componentDidUpdate
componentDidUpdate
方法是在组件在 DOM 中更新后调用的。
下面的示例可能看起来很复杂,但它所做的只是:
当组件安装时,它会以最喜欢的颜色"红色"呈现。
当组件已安装时,计时器会更改状态,并且颜色变为"黄色"。
这个动作触发了更新阶段,由于这个组件有一个 componentDidUpdate
方法,这个方法被执行并在空的 DIV 元素中写入一条消息 :
示例:
componentDidUpdate
方法在更新在 DOM 中呈现后被调用:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
componentDidMount() {
setTimeout(() => {
this.setState({favoritecolor: "yellow"})
}, 1000)
}
componentDidUpdate() {
document.getElementById("mydiv").innerHTML =
"The updated favorite is " + this.state.favoritecolor;
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<div id="mydiv"></div>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
Unmounting
生命周期的下一个阶段是从 DOM 中移除一个组件,或者 unmounting,就像 React 喜欢的那样。
React 只有一个内置方法,在卸载组件时会被调用:
componentWillUnmount()
componentWillUnmount
componentWillUnmount
方法在组件即将从 DOM 中移除时被调用。
示例:
点击按钮删除表头:
class Container extends React.Component {
constructor(props) {
super(props);
this.state = {show: true};
}
delHeader = () => {
this.setState({show: false});
}
render() {
let myheader;
if (this.state.show) {
myheader = <Child />;
};
return (
<div>
{myheader}
<button type="button" onClick={this.delHeader}>Delete Header</button>
</div>
);
}
}
class Child extends React.Component {
componentWillUnmount() {
alert("The component named Header is about to be unmounted.");
}
render() {
return (
<h1>Hello World!</h1>
);
}
}
ReactDOM.render(<Container />, document.getElementById('root'));