react---生命周期

news2025/4/21 20:22:16

目录

1.新旧生命周期对比

2.常用的3个钩子函数

3.生命周期(旧)

4.生命周期(新)


React 中为我们提供了一些生命周期钩子函数,让我们能在 React 执行的重要阶段,在钩子函数中做一些事情。

1.新旧生命周期对比

新的生命周期 对于 旧的生命周期 ,废弃(即将废弃)了 三个 生命钩子: componentWillMount、componentWillReceiveProps、componentWillUpdate

新提出了两个生命钩子:getDerivedStateFromProps(获取派生状态)、getSnapshotBeforeUpdate(存快照,比如用于存放滚动条更新前位置)

阶段旧生命周期新生命周期
初始化阶段:由ReactDOM.render() 触发 -----初次渲染

1. constructor()

2. componentWillMount()

3. render()

4. componentDidMount()  

1. constructor()

2. getDerivedStateFromProps()

 3. render()

 4. componentDidMount()

更新阶段

由组件内部this.setState() 或父组件render()触发

1. shouldComponentUpdate()----更新的阀门,要有return值,true或false

2. componentWillUpdate()

3. render()  

4. componentDidUpdate()

1. getDerivedStateFromProps()

2. shouldComponentUpdate()

3. render()

4. getSnapshotBeforeUpdate()

5. componentDidUpdate()

卸载组件:由ReactDOM.unmount

ComponentAtNode()

触发

componentWillUnmount()

2.常用的3个钩子函数

  •  render(): 初始化渲染或更新渲染调用
  •  componentDidMount():一般在这做一些初始化的事,例如:开启定时器、发送ajax请求、订阅消息
  • componentWillUnmount():一般在这做一些收尾的事,例如:清理定时器、取消订阅消息

3.生命周期(旧)

  • componentWillMount()---组件将要挂载
  •  componentDidMount()---组件已经挂载
  • componentWillUnmount() ---组件将要卸载
  • shouldComponentUpdate()---组件是否应该更新--更新的阀门,必须return true/false.主要用于性能优化,会对 props 和 state 进行浅层比较,并减少了跳过必要更新的可能性。不建议深层比较,会影响性能。如果返回false,则不会调用componentWillUpdate、render和componentDidUpdate
  • componentWillUpdate()---组件将要更新
  • componentDidUpdate()---组件已经更新
  • componentWillReceiveProps(props)---组件将要接收props,当父组件改变的时候,子组件会调这个钩子,初次渲染是不会执行这个钩子的。

componentWillMount、componentWillReceiveProps、componentWillUpdate生命周期方法经常被误解和滥用,新版本中并不推荐持有这三个函数,取而代之的是带有UNSAFE_ 前缀的三个函数,比如: UNSAFE_ componentWillMount。即便如此,其实React官方还是不推荐大家去使用,在以后版本中有可能会去除这几个函数。

【例子】

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    <script type="text/babel">
      class Count extends React.Component {
        constructor(props) {
          console.log("count--constructor--");
          super(props);
          this.state = { count: 0 };
        }
        // 组件将要挂载
        componentWillMount() {
          console.log("count--componentWillMount--");
        }
        // 组件已经挂载
        componentDidMount() {
          console.log("count--componentDidMount--");
        }
        // 组件将要卸载
        componentWillUnmount() {
          console.log("count--componentWillUnmount--");
        }
        // 组件是否应该更新--阀门
        shouldComponentUpdate() {
          console.log("count--shouldComponentUpdate--");
          return true;
        }
        // 组件将要更新
        componentWillUpdate() {
          console.log("count--componentWillUpdate--");
        }
        //组件已经更新
        componentDidUpdate() {
          console.log("count--componentDidUpdate--");
        }
        add = () => {
          let { count } = this.state;
          count++;
          this.setState({ count });
        };
        destroy = () => {
          ReactDOM.unmountComponentAtNode(document.getElementById("app"));
        };
        force = () => {
          this.forceUpdate();
        };
        render() {
          console.log("count--render--");
          let { count } = this.state;
          let { add, destroy, force } = this;
          return (
            <div>
              <h1>数据count:{count}</h1>
              <button onClick={add}>数据+1</button>
              <button onClick={destroy}>销毁组件</button>
              <button onClick={force}>强制更新</button>
            </div>
          );
        }
      }

      class A extends React.Component {
        state={carName:"奔驰"}
        changeCar=()=>{
          this.setState({carName:"奥拓"})
        }
        render() {
          let {carName}=this.state
          return (
            <div>
              <h1>我是A组件</h1>
              <button onClick={this.changeCar}>换车</button>
              <B carName={carName} />
            </div>
          );
        }
      }
      class B extends React.Component {
        //组件将要接收props
        componentWillReceiveProps(props){
          console.log("B--componentWillReceiveProps--",props);
        }
        shouldComponentUpdate(){
          console.log("B--shouldComponentUpdate--");
          return true
        }
        componentWillUpdate(){
          console.log("B--componentWillUpdate--");
        }
        componentDidUpdate(){
          console.log("B--componentDidUpdate-");
        }
        render() {
          console.log("B--render--");
          return (
            <div>
              <h1>我是B组件,接收的车是{this.props.carName}</h1>
            </div>
          );
        }
      }
      ReactDOM.render(<A/>, document.getElementById("app"));
    </script>
  </body>
</html>

4.生命周期(新)

getDerivedStateFromProps

  • 首先,该函数会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用;
  • 该函数必须是静态的;
  • 给组件传递的数据(props)以及组件状态(state),会作为参数到这个函数中;
  • 该函数也必须有返回值,返回一个Null或者state对象。因为初始化和后续更新都会执行这个方法,因此在这个方法返回state对象,就相当于将原来的state进行了覆盖,所以倒是修改状态不起作用。
  • 注意:如下代码【return props】时,state的值在任何时候都取决于传入的props,不能被改变
 // 若state值在任何时候都取决于props,那么可以使用getDerivedStateFromProps
 static getDerivedStateFromProps(props, state) {
    console.log("count--getDerivedStateFromProps--", props, state);
    // return props;
    return null
  }
....

 ReactDOM.render(<Count count={199}/>, document.getElementById("app"));

getSnapshotBeforeUpdate

可以使组件在 DOM 真正更新之前捕获一些信息(例如滚动位置),此生命周期返回的任何值都会作为参数传递给componentDidUpdate()。如不需要传递任何值,那么请返回 null

getSnapshotBeforeUpdate() {
  return this.refs.list.scrollHeight;
}
 //组件已经更新
componentDidUpdate(prevProps, prevState, snapshotValue) {
    console.log(prevProps, prevState, snapshotValue);
    this.refs.list.scrollTop+=this.refs.list.scrollHeight-snapshotValue
}

【例子-getSnapshotBeforeUpdate()用于记录上次滚动的位置】

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style>
        .news-wrapper{
            background-color: aquamarine;
            height: 150px;
            overflow: auto;
        }
        .news{
            height: 30px;
        }
    </style>
  </head>
  <body>
    <div id="app"></div>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    <script type="text/babel">
      class NewList extends React.Component {
        state = { newArr: [] };
        componentDidMount(){
            // console.log("--componentDidMount--");
            setInterval(()=>{
                let {newArr}=this.state
                let news ='新闻'+(newArr.length+1)
                this.setState({newArr:[news,...newArr]})
            },1000)
        }
        getSnapshotBeforeUpdate() {
          return this.refs.list.scrollHeight;
        }

        //组件已经更新
        componentDidUpdate(prevProps, prevState, snapshotValue) {
           console.log(prevProps, prevState, snapshotValue);
           this.refs.list.scrollTop+=this.refs.list.scrollHeight-snapshotValue
        }
        render() {
        //   console.log("--render--");
          return (
            <div ref="list" className="news-wrapper">
              {this.state.newArr.map((item, index) => {
               return <li key={index} className="news">{item}</li>;
              })}
            </div>
          );
        }
      }
      ReactDOM.render(<NewList />, document.getElementById("app"));
    </script>
  </body>
</html>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据安全--17--数据安全管理之数据传输

本博客地址&#xff1a;https://security.blog.csdn.net/article/details/131061729 一、数据传输概述 数据传输有两个主体&#xff0c;一个是数据发送方&#xff0c;另一个是数据接收方。数据在通过不可信或者较低安全性的网络进行传输时&#xff0c;容易发生数据被窃取、伪…

Mybatis源码学习之全局配置文件和映射文件解析

全局配置文件和映射文件解析 全局配置文件解析 public static void main(String[] args) throws IOException {// 读取配置文件InputStream is Resources.getResourceAsStream("org/apache/ibatis/builder/MapperConfig1.xml");// 创建SqlSessionFactory工厂SqlSes…

JDK11 官网下载(提供网盘下载资源)

目录 引言一、Oracle&#xff08;甲骨文&#xff09;二、JDK11下载1.JDK11下载入口2.JDK版本说明3.JDK11下载前说明4.JDK11下载 三、网盘下载1.资源提供说明2.资源列表清单&#xff08;持续更新中...&#xff09;3.获取方式 总结 引言 我们要学习 Java 语言去开发 Java 程序&a…

k8s 基本架构

k8s 中支持的 node 数 和 pod 数 k8s 也是逐步发展过来的&#xff0c;来看看以前和现在支持的 node 数 和 pod 数对比 node 即 节点 &#xff0c; 早期的 k8s 版本能够支持 100 台节点&#xff0c;现在 k8s 可以支持到 2000 台了 pod 数&#xff0c;早期的版本可以支持 1000 …

Android 自定义View 之 Dialog弹窗

Dialog弹窗 前言正文一、弹窗视图帮助类二、弹窗控制类三、监听接口四、样式五、简易弹窗六、常规使用七、简易使用八、源码 前言 在日常开发中用到弹窗是比较多的&#xff0c;常用于提示作用&#xff0c;比如错误操作提示&#xff0c;余额不足提示&#xff0c;退出登录提示等&…

linux 内核版本和发行版本

当要明确自己的Linux系统的版本号时&#xff0c;大多数情况是用命令确定Linux内核版本的。不过这个还是要与CentOS的版本号&#xff08;就是你使用的Linux系统的发行版本&#xff09;区分开来&#xff0c;这两个不是一个东西。 一、发行版本号 比如当时安装CentOS时&#x…

【Python】集合 set ① ( 集合定义 | 集合特点 | 代码示例 - 集合定义 )

文章目录 一、集合特点二、集合定义三、代码示例 - 集合定义 一、集合特点 在之前 的博客中 介绍了 列表 / 元组 / 字符串 数据容器 , 列表 支持 定义后 , 增加元素 / 修改元素 / 删除元素 , 并且 列表中可以存储 重复 / 有序 的元素 ;元组 定义后 不能 进行 增加元素 / 修改元…

(转载)有导师学习神经网络的回归拟合(matlab实现)

神经网络的学习规则又称神经网络的训练算法&#xff0c;用来计算更新神经网络的权值和阈值。学习规则有两大类别&#xff1a;有导师学习和无导师学习。在有导师学习中&#xff0c;需要为学习规则提供一系列正确的网络输入/输出对(即训练样本),当网络输入时&#xff0c;将网络输…

对于Promise的理解

1.什么是回调地狱 多层异步函数的嵌套叫做回调地狱 代码1&#xff1a; setTimeout(() > {console.log(吃饭);setTimeout(() > {console.log(睡觉);setTimeout(() > {console.log(打豆豆);}, 1000);}, 2000);}, 3000); 代码2: 通过id获取用户名,通过用户名获取邮箱…

如何自动识别快递单号和批量查询的方法

最近有很多朋友问我&#xff0c;有没有办法批量查询快递单号&#xff0c;查询该快递单号的所有物流发货信息&#xff1f;今天小编就来分享一个实用的查询技巧&#xff0c;教大家轻松查询多个快递单号&#xff0c;还可以一键保存查询数据&#xff0c;一起来看看吧。 首先今天我们…

PoseNet深度网络进行6D位姿估计的训练,python3实现

0.相关github网址 原版github代码-caffe实现tensorflow实现&#xff0c;相关版本较低&#xff0c;python2&#xff0c;本文根据此代码迁移到python3上面。pytorch实现&#xff0c;但将骨干模型从goglenet改成了resnet&#xff0c;实验效果得到提升&#xff0c;但没公布预训练权…

快递单号一键批量查询的具体操作方法和步骤

最近做电商的朋友对一个话题很感兴趣&#xff1a;如何批量查询快递单号&#xff1f;今天&#xff0c;小编给你安利一款软件&#xff1a;固乔快递查询助手&#xff0c;支持大量快递单号的批量查询。下面我们来看看批量查询的具体操作方法。 小伙伴们需要先在“固乔科技”的官网上…

session与cookie的来源与区别

目录 1.什么是HTTP&#xff1f; 2.cookie 3.session 4.cookie和session的区别 如果你对于session 和cookie 只有一点模糊理解&#xff0c;那么此文章能帮你更深入理解session和cookie &#xff0c;依旧和上篇文章一样&#xff0c;我们采用问题的方式来一步步探索&#xff0…

第七章 测试

文章目录 第七章 测试7.1 编码7.1.1 选择程序设计语言1. 计算机程序设计语言基本上可以分为汇编语言和高级语言2. 从应用特点看&#xff0c;高级语言可分为基础语言、结构化语言、专用语言 7.1.2 编码风格 7.2 软件测试基础7.2.1 软件测试的目标7.2.2 软件测试准则7.2.3 测试方…

JVM基础面试题及原理讲解

基本问题 介绍下 Java 内存区域&#xff08;运行时数据区&#xff09;Java 对象的创建过程&#xff08;五步&#xff0c;建议能默写出来并且要知道每一步虚拟机做了什么&#xff09;对象的访问定位的两种方式&#xff08;句柄和直接指针两种方式&#xff09; 拓展问题 Strin…

Flutter Widget 生命周期 key探究

Widget 在Flutter中&#xff0c;一切皆是Widget&#xff08;组件&#xff09;&#xff0c;Widget的功能是“描述一个UI元素的配置数据”&#xff0c;它就是说&#xff0c;Widget其实并不是表示最终绘制在设备屏幕上的显示元素&#xff0c;它只是描述显示元素的一个配置数据。 …

分库分表 21 招

&#xff08;一&#xff09;好好的系统&#xff0c;为什么要分库分表&#xff1f; 咱们先介绍下在分库分表架构实施过程中&#xff0c;会接触到的一些通用概念&#xff0c;了解这些概念能够帮助理解市面上其他的分库分表工具&#xff0c;尽管它们的实现方法可能存在差异&#…

自动化测试框架seldom

创建项目 | seldom文档 这个框架还是不错的&#xff0c;一直在优化&#xff0c;测试框架里的功能这里都有了。 seldom继承unittest单元测试框架&#xff0c;可以用来做UI和接口自动化项目。 安装 pip install seldom 创建项目 > seldom -P mypro 创建测试用例 # tes…

第8章 维护

文章目录 第8章 维护一、软件交付使用的工作二、软件交付使用的方式1) 直接方式2) 并行方式3) 逐步方式 8.1 软件维护的定义1、软件维护的定义2、软件维护的原因3、软件维护的类型1、改正性维护2、适应性维护3、完善性维护4、预防性维护 8.2 软件维护的特点8.2.1结构化维护和非…

12.异常-Exception|Java学习笔记

文章目录 异常介绍异常体系图一览运行时异常编译异常异常处理异常处理的方式try-catch 异常处理throws 异常处理注意事项和使用细节 自定义异常自定义异常的步骤 throw和throws的区别 异常介绍 基本概念&#xff1a;Java语言中&#xff0c;将程序执行中发生的不正常情况称为“…