生命周期图谱: React lifecycle methods diagram

生命周期三大阶段

挂载阶段

流程: constructor ==> render ==> componentDidMount

触发: ReactDOM.render(): 渲染组件元素

更新阶段

流程: render ==> componentDidUpdate

触发: setState() , forceUpdate(), 组件接收到新的props

卸载阶段

流程: componentWillUnmount

触发: 不再渲染组件

1.挂载阶段示例

父组件代码App.jsx

import React, { Component } from "react";

import Child from "./components/Child21";

export default class App extends Component {

constructor() {

super()

console.log("App constructor");

}

render() {

console.log("App render");

return (

App

);

}

componentDidMount() {

console.log("App componentDidMount");

}

}

子组件代码 Child.jsx

import React, { Component } from 'react'

export default class Child extends Component {

constructor(){

super()

console.log(' child constructor')

}

render() {

console.log('child render')

return (

Child

)

}

componentDidMount(){

console.log('child componentDidMount')

}

}

如图所示:

以上跟据生命周期图谱可得

初始化时,首先运行constructor()进行组件实例化与状态初始化。随后执行render()方法生成组件的虚拟DOM,并在此过程中同样按照此顺序执行所有子组件的构造函数及render方法。组件首次渲染到DOM后,触发componentDidMount();在组件接收到新的props或state并完成渲染更新后,则执行componentDidUpdate()方法。这两个方法常用于在组件挂载后或更新后的附加处理操作。

2.更新阶段示例

触发组件能够重 新render的条件有三个

1:new Props:组件接收到新的props

2:setState

3:forceUpdate()  强制更新

App.jsx

import React, { Component } from 'react'

import Child from './components/Child22'

// import Life from './components/Life'

export default class App extends Component {

// component组件 Did 完成 Mount 挂载

componentDidMount() {

console.log('App componentDidMount')

/**

* 1. 请求ajax数据

* 2. 频道订阅

* 3. 开启定时器

*/

}

// 定义状态

state = {

count:0

}

constructor() {

super()

console.log('App constructor')

// 可以修改状态,但是不触发render方法 this.setState

this.state.count = 1

// 增加状态

this.state.msg = 'AAA'

}

render() {

console.log('App render')

// console.log(this.state)

let {count,msg} = this.state

return (

App

state-- count: {count}

state-- msg : {msg}



{/* */}

)

}

}

Child.jsx

import React, { Component } from 'react'

export default class Child extends Component {

constructor(){

super()

console.log(' child constructor')

}

render() {

console.log('child render')

let {count} = this.props

return (

Child

props-- count : {count}

)

}

componentDidMount(){

console.log('child componentDidMount')

}

}

由此可得:当有组件嵌套的时候,父组件更新了,子组件不管数据是否发生变化,一律无脑更新  

另外:自身状态[state]和外部传入数据[props],都不改变的时候,不执行render方法

3.shouldComponentUpdate 确定是否可以跳过重新渲染

官方文档:Component – React 中文文档

shouldComponentUpdate(nextProps, nextState, nextContext)

nextProps:组件即将用来渲染的下一个 props。将 nextProps 与 this.props 进行比较以确定发生了什么变化。nextState:组件即将渲染的下一个 state。将 nextState 与 this.state 进行比较以确定发生了什么变化。nextContext:组件将要渲染的下一个 context。将 nextContext 与 this.context 进行比较以确定发生了什么变化。仅当你指定了 static contextType(更新的)或 static contextTypes(旧版)时才可用。

返回值 

如果你希望组件重新渲染的话就返回 true。这是也是默认执行的操作。

返回 false 来告诉 React 可以跳过重新渲染。

/**

*

* @param {*} nextProps 要更新的最新的props

* @param {*} nextState 要更新的最新的state

*/

shouldComponentUpdate(nextProps,nextState){

// console.log('nextProps',nextProps)

// console.log(this.props);

//return true; // 更新

//return false; // 不更新,后续render不会执行

// 判定外部传入的props变化与否

for(let attr in nextProps){

if(nextProps[attr] !== this.props[attr]){

return true;

}

}

// 判定自身状态变化,是否需要更新

for(let attr in nextState){

if(nextState[attr] !== this.state[attr]){

return true;

}

}

return false;

}

3.卸载阶段示例

componentWillUnmount: 组件即将卸载前执行

App.jsx 父组件代码

import React, { Component } from 'react'

import Life from './components/Life24'

export default class App extends Component {

// 定义状态

state = {

flag:true

}

render() {

let {flag} = this.state

return (

App


{ flag && }

)

}

}

Life.jsx 组件代码

import React, { Component } from "react";

export default class Life extends Component {

constructor() {

super();

console.log("Life constructor");

}

render() {

console.log("Life render");

return

Life
;

}

componentDidMount() {

console.log("Life componentDidMount");

}

componentWillUnmount() {

console.log("Life componentWillUnmount");

}

}

总结:

生命周期钩子

constructor: 只执行一次: 创建组件对象挂载第一个调用 用于初始化state属性或其它的实例属性或方法(可以简写到类体中) render: 执行多次: 挂载一次 + 每次state/props更新都会调用 用于返回要初始显示或更新显示的虚拟DOM界面 componentDidMount: 执行一次: 在第一次调用render且组件界面已显示之后调用 用于初始执行一个异步操作: 发ajax请求/启动定时器等 应用:

启动定时器 订阅消息 发送ajax请求 componentDidUpdate: 执行多次: 组件界面更新(真实DOM更新)之后调用 用于数据变化后, 就会要自动做一些相关的工作(比如: 存储数据/发请求) 用得少 => 这次我们先简单了解, 后面需要时再深入说 componentWillUnmount: 执行一次: 在组件卸载前调用 用于做一些收尾工作, 如: 清除定时器、取消订阅

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: