React生命周期

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

比如挂载阶段(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.state
    return (
      <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.state
    return (
      <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.state

    return (
      <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.state

    return (
      <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

上文已有介绍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/27969.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring集成Kafka

前言 我负责的其中一个项目&#xff0c;接口的交互量在千万级/d&#xff0c;所以要存储大量的日志&#xff0c;为了防止日志的存储影响到系统的性能&#xff0c;所以在技术选型就决定了使用Kafka中间件和一个日志存储系统来负责日志的存储。 使用Kafka 的优点&#xff1a; 1.…

图书推荐|大数据从业人人必备的Excel大数据处理分析

《Excel大数据处理&分析》为活页式新形态教材&#xff0c;介绍了Excel 2016的数据表基本操作、数据输入、数据获取、数据排序、数据筛选、分类汇总、公式与函数、日期和时间函数、数学和统计函数、查找和引用函数、数据透视表、图表的可视化分析、宏和VBA、数据分析工具的应…

23年软件测试前景和出路?新人入行测试怎样走“正确“的路...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 现在面试&#xf…

金融计量学第1节课:股指收益率序列统计特征

量化策略开发&#xff0c;高质量社群&#xff0c;交易思路分享等相关内容 导论与介绍 大家好&#xff0c;我是Le Chiffre 今天我们来为大家分享金融计量学系列内容&#xff0c;在松鼠量化3年多分享的内容中&#xff0c;大部分以量化策略为主&#xff0c;至今为止&#xff0c;…

Kotlin Lambda表达式和匿名函数的组合简直太强了

Kotlin Lambda表达式和匿名函数的组合简直太强了 简介 首先&#xff0c;在 Kotlin 中&#xff0c;函数是“第一公民”&#xff08;First Class Citizen&#xff09;。因此&#xff0c;它们可以被分配为变量的值&#xff0c;作为其他函数的参数传递或者函数的返回值。同样&…

【Excelc超实用快捷键!!!办公效率1000%up!up!up!】

目录索引 ctrle&#xff1a;提取数据&#xff1a;合并数据&#xff1a; 普通快捷键&#xff1a;ctrla&#xff1a;ctrlc&#xff1a;ctrlv&#xff1a;ctrlx&#xff1a;ctrlz&#xff1a;ctrly&#xff1a;ctrls&#xff1a;ctrlf&#xff1a; 文字格式快捷键&#xff1a;ctrl…

Python程序设计基础:数值

文章目录 一、数值数据类型二、python内置的数值操作三、math库 一、数值数据类型 Python语言可以很方便的用于处理数值运算问题&#xff0c;在数值运算过程中&#xff0c;常见的额两种数据类型分别为整数类型&#xff08;int&#xff09;和浮点类型&#xff08;float&#xf…

局域网内不同网段的设备互相连接设置

目录 介绍1、打开网络连接&#xff0c;找到本地网络->属性->ipv4->属性->高级&#xff1a;2、在高级设置页面&#xff0c;我们添加一个IP&#xff0c;这个IP和板子在一个网段&#xff0c;我这里设置的是192.168.253.101&#xff1a;3、设置完成即可生效&#xff0c…

Jetpack Compose ——Row

当我们构建界面时&#xff0c;经常需要在Compose中使用Row布局来水平排列多个组件。Row提供了一种方便的方式来管理和定位子组件&#xff0c;使它们按照我们期望的方式呈现。 在Compose中&#xff0c;Row可以接受多个子组件作为参数&#xff0c;并根据指定的布局规则进行排列。…

ChatGPT 应用——使用 chatGPT 写高考作文

写作文&#xff0c;很简单&#xff0c;但写一篇好的作文&#xff0c;是非常有难度的。 想要写一篇高分作文&#xff0c;需要对作文题目有正确的理解&#xff0c;需要展现独到的观点和深入的思考&#xff0c;需要具备清晰的逻辑结构&#xff0c;需要准确而得体的语言表达。 正…

金鸣识别的表格分析技术揭秘

表格分析是指将图片中的表格区域分割出来&#xff0c;并识别出表格中的单元格和单元格中的内容。表格分析技术主要包括以下几个步骤&#xff1a; 1. 表格检测&#xff1a;通过图像处理技术&#xff0c;将图片中的表格区域分割出来。 2. 单元格分割&#xff1a;将表格中的每个单…

Unity入门4——重要组件与API

一、GameObject &#xff08;一&#xff09;成员变量 // 名字 print(this.gameObject.name); this.gameObject.name "Lesson4唐老狮改名"; print(this.gameOb…

简单使用Hystrix

使用Hystrix之前&#xff0c;需要先对SpringCloud有所了解&#xff0c;然后才会使用的顺畅&#xff0c;它是我们SpringCould的一种保护机制&#xff0c;非常好用。 下面直接开始 先导入Hystrix所需要的依赖 <!-- 引入openfiegn--> <dependency> <groupId>org…

图解数据结构--栈的实现-C语言版本--源码

目录-总 -分- 总结构 图片可视化 总源码1.头文件介绍---分2.节点的实现3.栈顶栈底4.函数的提前声明5. 栈 ---初始化栈6. 栈 ---进栈7.栈 --- 遍历8.栈 --- 是否为空9.栈 --- 出栈10总结 图片可视化 总 源码 /*time 2023年6月12日12:39:06auther yzmcntent stract 栈 */#inclu…

SpringBoot整合ShardingSphere5.x实现数据加解密功能

环境&#xff1a;Springboot2.6.14 ShardingSphere5.3.0 准备环境 添加依赖 <dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core</artifactId><version>${shardingsphere.version}</ve…

适合做读书笔记的工具 这款APP满足你的笔记需求

说到读书&#xff0c;就免不了要提到读书笔记。很多人认为&#xff0c;边读书边做笔记才能更好地帮助我们更深入地理解和记忆所读的书籍内容。通过记录书中的重要观点、论据、事实和例子&#xff0c;我们可以更好地掌握书中的知识和思想&#xff0c;而不是仅仅浏览、快速阅读或…

vscode右键点击,松开后自动触发鼠标所在位置的按钮(误触发双击效果)

例如如下&#xff0c;右键展开菜单&#xff0c;松手会自动触发转到声明功能 解决方案&#xff1a; 1、安装easystroke sudo apt-get install easystroke 2、打开easystroke&#xff0c;选择preferences tab 3、点击Gesture Button&#xff0c;在出现的框中右键单击一次 4、点…

Mocha Pro:AdjustTrack 模块

跟踪时由于缺乏细节或有障碍物阻挡&#xff0c;跟踪点发生了漂移&#xff0c;或者一个或多个跟踪点可能会离开画面&#xff0c;此时可考虑使用 AdjustTrack &#xff08;调整跟踪&#xff09;模块手动设置关键帧来获得更精准的跟踪数据。 尤其是当要利用表面 Surface区域进行插…