React生命周期

news/2024/11/27 17:55:18/

生命周期是一个抽象的概念,在生命周期的整个过程,分成了很多个阶段:

比如挂载阶段(Mount),组件第一次在DOM树中被渲染的过程;

比如更新过程(Update),组件状态发生变化,重新更新渲染的过程;

比如卸载过程(Unmount),组件从DOM树中被移除的过程;

React内部为了告诉我们当前处于哪些阶段,会对我们组件内部实现的某些函数进行回调,这些函数就是生命周期函数:

  • 比如实现componentDidMount函数:组件已经挂载到DOM上时,就会回调;
  • 比如实现componentDidUpdate函数:组件已经发生了更新时,就会回调;
  • 比如实现componentWillUnmount函数:组件即将被移除时,就会回调;

因此我们可以在这些回调函数中编写自己的逻辑代码,来完成自己的需求功能;

1、常用生命周期

在这里插入图片描述

1.1 挂载阶段

1、在挂载阶段,即创建组件实例的时候会先执行组件的constructor方法

  • 如果不初始化 state 或不进行方法绑定,则不需要为 React 组件实现构造函数

constructor中通常只做两件事情:

1、通过给 this.state 赋值对象来初始化内部的state
2、为事件绑定实例(this)

2、紧接着会执行组件的render方法
3、最后会执行 componentDidMount 方法, 该方法会在组件挂载后(插入 DOM 树中)立即调用

  • 依赖于DOM的操作可以在这里进行
  • 此处是发送网络请求最好的地方(官方建议)
  • 可以在此处添加一些订阅(会在componentWillUnmount取消订阅)

Hello.jsx

import React from 'react';export default class Hello extends React.Component{constructor() {super()console.log('hello constructor')}render() {console.log('hello render')return (<h1>hello</h1>)}
}

App.jsx

import React from 'react'
import Hello from './Hello'export default class App extends React.Component {render() {return (<div><Hello /><Hello /></div>)}
}

在这里插入图片描述
可见如果使用多次组件实例,该组件每次挂载时都会先执行constructor方法再执行render方法
如果在class组件中定义了componentDidMount函数,那么当组件挂载完毕后会被回调:

import React from 'react';export default class Hello extends React.Component{constructor() {super()console.log('hello constructor')}render() {console.log('hello render')return (<h1>hello</h1>)}componentDidMount() {console.log('componentDidMount...')}
}

在这里插入图片描述

1.2 更新阶段

一旦执行了this.setState方法就会触发组件的更新:

  1. 此时会立即执行组件的render方法
  2. 在组件更新完后componentDidUpdate会被立即调用
import React from 'react';export default class Hello extends React.Component{constructor() {super()this.state = {message: 'hello world'}console.log('hello constructor')}changeText() {this.setState({ message: 'hello react'})}render() {console.log('hello render')const {message} = this.statereturn (<div><h1>{message}</h1><button onClick={() => this.changeText()}>修改</button></div>)}componentDidMount() {console.log('componentDidMount...')}componentDidUpdate() {console.log('componentDidUpdate...')}
}

在这里插入图片描述

1.3 卸载阶段

componentWillUnmount 方法会在组件卸载及销毁之前直接调用 :

  • 在此方法中执行必要的清理操作
  • 例如,清除 timer,取消网络请求或清除在 componentDidMount() 中创建的订阅等

Hello.jsx

import React from 'react';export default class Hello extends React.Component{constructor() {super()this.state = {message: 'hello world'}console.log('hello constructor')}render() {console.log('hello render')const {message} = this.statereturn (<div><h1>{message}</h1></div>)}componentDidMount() {console.log('componentDidMount...')}componentWillUnmount() {console.log('componentWillUnmount...')}
}

App.jsx

import React from 'react'
import Hello from './Hello'export default class App extends React.Component {constructor() {super()this.state = {isShow: true}}changeShow() {this.setState({ isShow: !this.state.isShow})}render() {return (<div><button onClick={() => this.changeShow()}>切换</button>{ this.state.isShow && <Hello />}</div>)}
}

在这里插入图片描述

2、不常用生命周期

在这里插入图片描述

2.1 挂载阶段

在挂载阶段,执行完毕constructor后还会执行 static getDerivedStateFromProps() 方法,执行顺序依次为:

  1. constructor()
  2. static getDerivedStateFromProps()
  3. render()
  4. componentDidMount()

static getDerivedStateFromProps(props, state)

该方法使用场景比较罕见,如果state的值在任何时候都依赖于props时才使用此方法

  • 该方法会在render前被调用,并且在初始挂载及后续更新时都会被调用
  • 该方法会返回一个对象来更新state,如果返回null则不更新任何内容
  • 该方法的存在只有一个目的:让组件在props变化时来更新state

2.2 更新阶段

在更新阶段会依次执行:

  1. static getDerivedStateFromProps()
  2. shouldComponentUpdate()
  3. render()
  4. getSnapshotBeforeUpdate()
  5. componentDidUpdate()

shouldComponentUpdate(nextProps, nextState)

当props或state发生变化时,该方法会在渲染之前被调用,返回值默认是true,如果返回false则不重新渲染组件。

  • 该方法常用于性能优化,不要企图依靠此方法来阻止渲染,因为这可能会产生bug
  • 如果返回了false则不会执行rendercomponentDidUpdate

App.jsx

import React from "react"
import HelloWorld from "./HelloWorld"class App extends React.Component {render() {return (<div><HelloWorld/></div>)}
}export default App

HelloWord.jsx

import React from "react"class HelloWorld extends React.Component {constructor() {console.log("constructor...")super()this.state = {message: "Hello World"}}changeText() {this.setState({ message: "Hello React" })}render() {console.log("render...")const { message } = this.statereturn (<div><h2>{message}</h2><button onClick={e => this.changeText()}>修改文本</button></div>)}componentDidMount() {console.log("componentDidMount...")}componentDidUpdate() {console.log("componentDidUpdate...")}shouldComponentUpdate() {return true}
}export default HelloWorld

如果 shouldComponentUpdate()返回了true,在点击按钮修改文本时:
在这里插入图片描述
如果 shouldComponentUpdate()返回了false,在点击按钮修改文本时:

 shouldComponentUpdate() {return false}

在这里插入图片描述

getSnapshotBeforeUpdate(prevProps, prevState)

该方法会在componentDidUpdate之前被调用,可以用来在组件发生变更前从DOM中捕获一些信息(如滚动位置)。

  • 该方法返回的内容会作为参数传递给componentDidUpdate
import React from "react"class HelloWorld extends React.Component {constructor() {console.log("constructor...")super()this.state = {message: "Hello World"}}changeText() {this.setState({ message: "Hello React" })}render() {console.log("render...")const { message } = this.statereturn (<div><h2>{message}</h2><button onClick={e => this.changeText()}>修改文本</button></div>)}componentDidMount() {console.log("componentDidMount...")}componentDidUpdate(prevProps, prevState, snapshot) {console.log("componentDidUpdate...", prevProps, prevState, snapshot)}getSnapshotBeforeUpdate() {console.log('getSnapshotBeforeUpdate...')return {scrollTop: 100}}
}export default HelloWorld

在这里插入图片描述

3、对比老版生命周期

3.1 react生命周期(旧)

在这里插入图片描述

3.2 react生命周期(新)

在这里插入图片描述

3.3 对比

通过两个图的对比,可以发现新版的生命周期减少了以下三种方法:

  1. componentWillMount
  2. componentWillReceiveProps
  3. componentWillUpdate

其实这三个方法仍然存在,只是在前者加上了UNSAFE_前缀,如UNSAFE_componentWillMount,并不像字面意思那样表示不安全,而是表示这些生命周期的代码可能在未来的 react版本可能废除

同时也新增了两个生命周期函数:

  1. getDerivedStateFromProps
  2. getSnapshotBeforeUpdate

上文已有介绍


http://www.ppmy.cn/news/350558.html

相关文章

Spark大数据处理学习笔记1.4 掌握Scala运算符

文章目录 一、学习目标二、运算符等价于方法&#xff08;一&#xff09;运算符即方法&#xff08;二&#xff09;方法即运算符1、单参方法2、多参方法3、无参方法 三、Scala运算符&#xff08;一&#xff09;运算符分类表&#xff08;二&#xff09;Scala与Java运算符比较 四、…

android 局域网对讲机

参考了一些代码&#xff0c;实现了局域网的实时语音对讲功能&#xff0c;只要同网段局域网即可通话&#xff0c;文字聊天&#xff0c;传输文件等&#xff0c;包含了飞鸽传输的功能。 主要是录音发送和接收播放录音比较重要。录音线程&#xff1a; Java代码 public class Audi…

【对讲机的那点事】玩公网对讲机,你知道公网对讲机的模块吗?

公网对讲机模块的大量使用&#xff0c;让终端厂家的开发、生产变得相当容易&#xff0c;有人说&#xff0c;模块是实现复杂到简单的桥梁&#xff0c;是托起行业发展的翅膀&#xff0c;但是有多少公网集群对讲机经销商对公网对讲机模块有过了解吗&#xff1a; 如果说模拟集群向数…

【对讲机的那点事】免费的公网对讲机平台你敢用吗?

公网对讲由前几年的概念阶段到现在迅速爆发阶段,凭借其音质清晰、没有距离限制、GPS定位、单呼选呼等集群功能强大等优势迅速占据了对讲市场的半壁江山,但是公网对讲也有他的短板,即公网对讲的使用是需要收费的,这也是部分用户不选择公网对讲的原因之一,下面我们就把公网对…

this 关键字的用法,super 关键字的用法,this 与 super 的区别

this 是自身的一个对象&#xff0c;代表对象本身&#xff0c;是指向对象本身的一个指针。 用法分为3种&#xff1a; 1.普通的直接引用&#xff0c;this 相当于是指向当前对象本身 2.形参与成员名字重名&#xff0c;用this 来区分 public Student(String name, int age) {this.…

Vue第八篇Vue3

一 Vue3的变化 1.性能的提升 打包大小减少41% 初次渲染快55%, 更新渲染快133% 内存减少54% 2.源码的升级 使用Proxy代替defineProperty实现响应式 重写虚拟DOM的实现和Tree-Shaking 3.拥抱TypeScript Vue3可以更好的支持TypeScript 4.新的特性 Composition API&#…

计算机各外设的作用,计算机外设的功能是什么

外部设备简称“外设”&#xff0c;是指连在计算机主机以外的硬件设备。对数据和信息起着传输、转送和存储的作用&#xff0c;是计算机系统中的重要组成部分。随着我国计算机应用的迅速普及以及网络化、信息化应用的日益广泛&#xff0c;使市场对计算机外部设备的需求不断增长&a…

小学是不是可以用计算机,小学生怎样利用计算机学习

计算机(computer)俗称电脑&#xff0c;是一种用于高速计算的电子计算机器&#xff0c;可以进行数值计算&#xff0c;又可以进行逻辑计算&#xff0c;还具有存储记忆功能。下面是unjs小编整理的相关内容&#xff0c;欢迎大家阅读! (1)学习学校知识 同学们可以依靠计算机来学习学…