React(8)React组件的生命周期


前言

本篇文章我们来系统的讲解React组件的生命周期。React随着版本的不断提升,组件的生命周期也在不断地改版和升级。本篇文章以React 17为例,讲解最新版React的组件生命周期,同时阐述各个生命周期所执行的生命周期函数。


一、React组件的生命周期

React 17将组件的生命周期分为以下三个阶段:

  • 组件的挂载阶段(Mounting)
  • 组件的更新阶段(Updating)
  • 组件的卸载阶段(Unmounting)

二、React组件的挂载阶段

在React中,将组件第一次插入至DOM树中渲染的过程称之为“挂载”。挂载阶段要完成组件状态的初始化、创建API调用请求、启动或停止计时器、操作已渲染的DOM、初始化第三方脚本库等工作。React组件挂载阶段涉及到以下四个生命周期函数。

  • constructor()
  • getDerivedStateFromProps()
  • render()
  • componentDimMount()

1、constructor()构造函数

从原理上来讲,constructor()构造函数并不是一个生命周期函数,只是当组件挂载时,构造函数永远是第一个被触发的。构造函数的主要功能是初始化组件状态,即为state区设置初始化数据。
构造函数的格式如下所示。

class Comp extends react.Component{
  constructor(props){
    super(props);
    this.state={
      // 初始化React组件状态
    }
  }
}

2、getDerivedStateFromProps()生命周期函数

该函数是一个静态函数,使用时必须声明static关键字,且不能在其内部使用this关键字。同时使用时有两个参数:nextProps、prevState,分别用来表示父组件传递过来的参数对象和组件的state区数据对象。该生命周期函数在使用时有如下规定。

  • 组件必须在constructor()构造函数中设置state区,否则该函数会报错。
  • 该生命周期函数必须返回一个对象,或者返回null。

从这个生命周期函数的名字中就可以看出,它的功能是从props中获取state,即利用父组件传递过来的props属性来更新state数据。

例1:父组件调用子组件,并向Comp传递title和content两个参数。

父组件核心代码:

<Comp title="组件挂载" content="将组件第一次插入至DOM树中渲染"></Comp>

子组件代码:

class Comp extends React.Component{
  constructor(props){
    super(props);
    this.state={
      ca:15,
      cb:20
    }
    console.log(this.state);
  }
  static getDerviedStateFromProps(nextProps,prevState){
    console.log(nextProps);
    console.log(prevState);
    const {title,content} = nextProps;
    return {
      title,content
    }
  }
}

在上述代码中,组件Comp挂载阶段,先执行构造函数constructor(),再执行静态函数getDerviedStateFromProps()。所以在构造函数中输出this.state,结果为:{ca:15,cb:20}。

静态函数getDerviedStateFromProps()中nextProps参数是父组件向子组件传递的数据构成的对象,所以输出nextProps的结果为:{title:“组件挂载”,content:“将组件第一次插入至DOM树中渲染”}。

静态函数getDerviedStateFromProps()中返回的对象都是要加入到组件的state状态中的,所以父组件向子组件传递的title数据和content数据也会变为state状态区中的一部分。

3、render()渲染函数

render()渲染函数是React组件的必备函数,没有该函数React组件会报错。该函数用来返回使用JSX语法实现的组件内容,包括HTML标记对和JavaScript业务流程。在例1中,如果在render()函数中输出this.state,因为getDerviedStateFromProps()函数在render()函数之前执行,所以此时输出的结果为:{ca:15,cb:20,title:“组件挂载”, content:“将组件第一次插入至DOM树中渲染”}。

4、componentDidMount()生命周期函数

该函数是组件挂载阶段最后一个执行的生命周期函数,会在组件挂载成功且渲染完毕之后触发。项目开发过程中,多在该函数中调取API数据,例如使用Fetch、Axios技术从后台获取组件使用的数据。

三、React组件的更新阶段

在React中,将组件重新渲染的过程称之为“更新”。当组件的state数据发生变化或从父组件接收到新的属性时进入到组件的更新阶段,即调用this.setState()方法时,组件会启动更新阶段。React组件更新阶段涉及到以下五个生命周期函数。

  • getDerviedStateFromProps()
  • shouldComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

首先,要重点声明。上述函数都是在组件更新时触发的生命周期函数,即一旦执行了this.state()方法,上述函数就会依次执行一遍。也就是说,如果在上述函数中调用了this.state()方法,将会使更新生命周期引发无限递归循环,从而导致堆栈溢出。因此上述函数中不得调用this.state()方法。render()函数中元素的事件函数除外,因为事件函数虽然书写在render()函数内部,但是并不自动执行,因此不会导致堆栈溢出。

1、shouldComponentUpdate()生命周期函数

该生命周期函数有两个参数:nextProps、prevState,分别用来表示父组件传递过来的参数对象和组件的state区数据对象。
该生命周期函数被称为更新阶段的“门卫”,在使用时必须返回一个逻辑值,以表示后面的更新生命周期函数是否继续执行。

  • 返回true,表示继续执行组件的更新生命周期函数。
  • 返回false,表示不再继续执行组件的更新生命周期函数。

这里需要注意,该生命周期函数返回false,只表示不再继续执行后面的生命周期函数,触发更新声明周期启动的this.setState()方法依然会成功执行。

例2:当更新state区中的title数据时,判断父组件传递的title是否与更新后的title一致,如一致就停止执行生命周期过程;如不一致则继续执行生命周期过程。

class Comp extends Component {
  constructor(props){
    super(props);
    this.state={
      ca:15,
      cb:20
    };
  }
  shouldComponentUpdate(nextProps,prevState){
    if(nextProps.title!==prevState.title){
      return true;
    }
    return false;
  }
  btnClick(){
    this.setState({
      title:"你好"
    })
  }
  render() {
    console.log("Render函数");
    console.log(this.state);
    return (
      <Fragment>
        我是Comp组件
        <p><button onClick={()=>this.btnClick()}>单击我</button></p>
      </Fragment>
    );
  }
}

2、getSnapshotBeforeUpdate()生命周期函数

该生命周期函数在组件的更新阶段,在render()函数之后,组件DOM渲染之前触发。具备以下两个参数。

  • prevProps:依然表示父组件向子组件传递的数据。
  • prevState:依然表示state区中的数据。

该生命周期函数在使用时有如下两个规定:

  • 必须配合componentDidUpdate()生命周期函数共同使用。
  • 必须返回一个值,该值将作为componentDidUpdate()生命周期函数的第三个参数。

3、componentDidUpdate()生命周期函数

该生命周期函数在组件更新完成后触发,其语法格式如下所示。
componentDidUpdate(prevProps,prevState,snapshot){}

四、React组件的卸载阶段

在React中,从DOM树中删除组件的过程称之为“卸载”。该生命周期只有一个生命周期函数。

  • componentWillUnmount()

可以在该生命周期函数中清除timer计时器以及在componentDidMount()生命周期函数中声明的变量。


总结

本文是React系列教程的第八篇文章,主要为大家讲解了React 17中组件的生命周期与各个生命周期的函数。整体来说,生命周期函数的执行可以用下图来进行说明。
在这里插入图片描述

第一讲 初识React框架

第二讲 认识JSX语法格式

第三讲 React组件

第四讲 React 父子组件之间的通信

第五讲 React兄弟组件之间的通信

第六讲 React受控组件的使用

第七讲 React非受控组件的使用

关于作者

小海前端,具有18年Web项目开发和前后台培训经验,在前端领域著有较为系统的培训教材,对Vue.js、微信小程序开发、uniApp、React等全栈开发领域都有较为深的造诣。入住CSDN,希望能够更多的结识Web开发领域的同仁,将Web开发大力的进行普及。同时也愿意与大家进行深入的技术研讨和商业合作。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
函数式组件没有像类组件那样的生命周期方法,因为函数式组件是以纯函数的方式编写的,它们没有实例和状态的概念。然而,React 在函数式组件中引入了一些钩子函数来实现类似的功能。 1. useEffect:可以在函数式组件中使用 useEffect 钩子来处理副作用操作,比如订阅事件、发送网络请求、操作 DOM 等。它接收一个回调函数和一个依赖数组作为参数,回调函数会在每次渲染之后执行。依赖数组用于指定当某些值发生变时才重新执行回调函数。如果依赖数组为空,则回调函数只在组件首次渲染后执行一次。 2. useState:可以使用 useState 钩子来在函数式组件中管理状态。它返回一个状态值和一个更新状态的函数,可以通过解构赋值的方式进行使用。每次调用更新状态的函数时,组件会重新渲染。 3. useMemo 和 useCallback:这两个钩子函数可以用来优性能。useMemo 可以缓存计算结果,只有当依赖项发生变时才重新计算。useCallback 可以缓存函数,只有当依赖项发生变时才返回新的函数。 此外,React 还提供了一些其他的钩子函数,如 useContext、useReducer、useRef 等,用于处理上下文、状态管理和引用等。 总结来说,函数式组件生命周期可以通过 useEffect 和其他钩子函数来模拟和实现。它们提供了一种更简洁、灵活的方式来编写组件,并且能够满足大部分的开发需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小海前端

原创不易,量力支持,感谢打赏。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值