• React生命周期理解


     前言

    如果将React的生命周期比喻成一只蚂蚁爬过一根吊绳,那么这只蚂蚁从绳头爬到绳尾,就会依次触动不同的卡片挂钩。在React每一个生命周期中,也有类似卡片挂钩的存在,我们把它称之为‘钩子函数’。那么在React的生命周期中,到底有哪些钩子函数?React的生命周期又是怎样的流程?今天我给大家来总结总结

    如图,React生命周期主要包括三个阶段:初始化阶段、运行中阶段和销毁阶段,在React不同的生命周期里,会依次触发不同的钩子函数,下面我们就来详细介绍一下React的生命周期函数

    一、初始化阶段

    1、设置组件的默认属性

    1. static defaultProps = {
    2. name: 'sls',
    3. age:23
    4. };
    5. Counter.defaltProps={name:'sls'}

    2、设置组件的初始化状态

    1. constructor() {
    2. super();
    3. this.state = {number: 0}
    4. }

    3、componentWillMount()

    组件即将被渲染到页面之前触发,此时可以进行开启定时器、向服务器发送请求等操作

    4、render()

    组件渲染

    5、componentDidMount()

    组件已经被渲染到页面中后触发:此时页面中有了真正的DOM的元素,可以进行DOM相关的操作

    二、运行中阶段

    1、componentWillReceiveProps()

    组件接收到属性时触发

    2、shouldComponentUpdate()

    当组件接收到新属性,或者组件的状态发生改变时触发。组件首次渲染时并不会触发

    1. shouldComponentUpdate(newProps, newState) {
    2. if (newProps.number < 5) return true;
    3. return false
    4. }
    5. //该钩子函数可以接收到两个参数,新的属性和状态,返回true/false来控制组件是否需要更新;会在渲染执行之前被调用

    一般我们通过该函数来优化性能:

    一个React项目需要更新一个小组件时,很可能需要父组件更新自己的状态。而一个父组件的重新更新会造成它旗下所有的子组件重新执行render()方法,形成新的虚拟DOM,再用diff算法对新旧虚拟DOM进行结构和属性的比较,决定组件是否需要重新渲染

    无疑这样的操作会造成很多的性能浪费,所以我们开发者可以根据项目的业务逻辑,在shouldComponentUpdate()中加入条件判断,从而优化性能

    例如React中的就提供了一个PureComponent的类,当我们的组件继承于它时,组件更新时就会默认先比较新旧属性和状态,从而决定组件是否更新。值得注意的是,PureComponent进行的是浅比较,所以组件状态或属性改变时,都需要返回一个新的对象或数组

    3、componentWillUpdate()

    组件即将被更新时触发

    4、componentDidUpdate()

    组件被更新完成后触发。页面中产生了新的DOM的元素,可以进行DOM操作

    三、销毁阶段

    1、componentWillUnmount()

    组件被销毁时触发。这里我们可以进行一些清理操作,例如清理定时器,取消Redux的订阅事件等等。

    有兴趣的同学也可以用下面的代码进行测试

    废话少说,放码过来!

    1. import React from 'react'
    2. import ReactDOM from 'react-dom';
    3. class SubCounter extends React.Component {
    4. componentWillReceiveProps() {
    5. console.log('9、子组件将要接收到新属性');
    6. }
    7. shouldComponentUpdate(newProps, newState) {
    8. console.log('10、子组件是否需要更新');
    9. if (newProps.number < 5) return true;
    10. return false
    11. }
    12. componentWillUpdate() {
    13. console.log('11、子组件将要更新');
    14. }
    15. componentDidUpdate() {
    16. console.log('13、子组件更新完成');
    17. }
    18. componentWillUnmount() {
    19. console.log('14、子组件将卸载');
    20. }
    21. render() {
    22. console.log('12、子组件挂载中');
    23. return (
    24. <p>{this.props.number}p>
    25. )
    26. }
    27. }
    28. class Counter extends React.Component {
    29. static defaultProps = {
    30. //1、加载默认属性
    31. name: 'sls',
    32. age:23
    33. };
    34. constructor() {
    35. super();
    36. //2、加载默认状态
    37. this.state = {number: 0}
    38. }
    39. componentWillMount() {
    40. console.log('3、父组件挂载之前');
    41. }
    42. componentDidMount() {
    43. console.log('5、父组件挂载完成');
    44. }
    45. shouldComponentUpdate(newProps, newState) {
    46. console.log('6、父组件是否需要更新');
    47. if (newState.number<15) return true;
    48. return false
    49. }
    50. componentWillUpdate() {
    51. console.log('7、父组件将要更新');
    52. }
    53. componentDidUpdate() {
    54. console.log('8、父组件更新完成');
    55. }
    56. handleClick = () => {
    57. this.setState({
    58. number: this.state.number + 1
    59. })
    60. };
    61. render() {
    62. console.log('4、render(父组件挂载)');
    63. return (
    64. <div>
    65. <p>{this.state.number}p>
    66. <button onClick={this.handleClick}>+button>
    67. {this.state.number<10?<SubCounter number={this.state.number}/>:null}
    68. div>
    69. )
    70. }
    71. }
    72. ReactDOM.render(<Counter/>, document.getElementById('root'));

     

  • 相关阅读:
    pandas教程:Interacting with Web APIs API和数据库的交互
    Spring Messaging远程命令执行漏洞复现(CVE-2018-1270)
    vector容器模拟实现及使用——c++
    【C#】学习WPF的生产管理平台回顾与总结
    C++并发与多线程(6) | 传递临时对象作为线程参数的一些问题Ⅲ
    C++从零开始的打怪升级之路(day38)
    电脑里重要文件用什么备份,电脑如何备份主要数据
    苹果0day漏洞紧急修复;美国大力打击间谍软件公司;黑客利用Docker Redis漏洞进行挖矿| 安全周报 0308
    华为云云耀云服务器L实例评测|使用sysbench对云耀云服务器mysql的性能测试
    Redis String类型使用方法
  • 原文地址:https://blog.csdn.net/m0_60153106/article/details/126052257