什么是react生命周期和生命周期钩子函数?

2021-02-02 09:12发布

10条回答
芒果
2楼 · 2021-02-02 09:31

react生命周期钩子函数

初始化阶段

constructor                 初始化数据---初始化状态

componentWillMount            以前建议进行ajax请求,最后一次修改状态的机会,

                        但是现在基本上都componentDidMount中请求

render                    第一次装载(渲染)数据

componentDidMount             ajax请求,更新状态,进入运行时阶段,更新视图,还可以实例化一些对象

运行时阶段

componentWillReceiveProps       子组件接收到父组件的数据

shouldComponentUpdate          本组件是不是需要进行去更新视图,默认为true,

                        要不不写,写了必写返回值,false表示不更新视图

componentWillUpdate           组件即将被更新-----无实际意义

render                    重新渲染数据

componentDidUpdate            实例化一些对象(特别是如果数据是动态请求的)

销毁

componentWillUnmount          清除一些计时器,定时器等

错误异常处理

componentDidCatch

componentDidCatch  --- 错误边界作为 React 组件,用以捕获在子组件树中任何地方的 JavaScript 异常,打印这些错误,并展示备用 UI 而非让组件树崩溃。错误边界会捕获渲染期间,在生命周期方法中以及在其整个树的构造函数中的异常。

20200921文 - 做更棒的自己!
3楼 · 2021-02-02 09:41

如果将React的生命周期比喻成一只蚂蚁爬过一根吊绳, 那么这只蚂蚁从绳头爬到绳尾,就会依次触动不同的卡片挂钩。在React每一个生命周期中,也有类似卡片挂钩的存在, 我们把它称之为‘钩子函数’。

studentaaa
4楼 · 2021-02-02 09:41

什么是react生命周期函数

1. 组件中在某个阶段会自动执行的函数。
- 比如我们执行使用render函数,在prop或者state变化时,render函数自动执行。
- 因此render函数就是一个生命周期函数。
2. constructor在组件创建的时候也会自动调用。但是他不是react独有,是es6中的函数所以,我们不将他列为生命周期函数。

生命周期分为4个阶段

1. initialization(组件初始化)
- 我们在创建组件的时候需要继承react Component这个基类,也就继承这个react的基类,才能有render(),生命周期等方法可以使用,这也说明为什么函数组件不能使用这些方法的原因。同时也让组件能使用setState方法。
- 然后我们在 constructor 构造函数中使用 super(props)来将父组件传递的props注入给这个组件,以及使用this.state初始化这个组件的属性。
- 这一系列动作就是组件的初始化。
2. mount (组件的挂载)
- 此阶段分为三个时期
1. componentWillMount(挂载之前)
- 这个函数在组件挂载到DOM之前的时候执行,所以你在这里引用setState方法,是不会引起组件的重新渲染。
- 同样这里做的事情如果放在constructor构造函数中去使用也是可以的。
- 这个函数只会被调用一次,就是组件挂载到DOM之前的时候。其他时候是不会触发这个函数的。

2. render(挂载中)
- 根据组件的props和state是否变化,变化即执行,这里的变化要注意,并不是值变化。只要重新赋值,新旧值相同也会执行。
- 然后return 一个React元素(描述组件,即UI),不负责组件实际渲染工作,之后由React自身根据此元素去渲染出页面DOM。render是纯函数(Pure function:函数的返回结果只依赖于它的参数;函数执行过程里面没有副作用。
- 不能在里面执行this.setState,会有改变组件状态的副作用。

3. componentDidMount(挂载完成)
- 约定将ajax请求放在这个生命周期函数中
- 组件挂载到DOM后被执行,只会执行一次。
3. update (组件更新时)
- 首先我们来了解一下什么时组件更新。只有在通过setState函数使sate和props变化或重新赋值时才叫组件更新。
- setState引起父组件的render函数执行,同时也会引起它的子组件的render函数执行。
- 原因是react虚拟DOM的diff算法,同级比较原理。
- 只要重新赋值就是组件更新,如果值并没有变,也更新组件,这样就会耗性能,也是我们讲同级比较的时候说的一个弊端。

- 接下来我们了解一下有那些周期函数
1. componentWillReceiveProps(nextProps)
- 此方法只调用于props引起的组件更新过程中,参数nextProps是父组件传给当前组件的新props。但父组件render方法的调用不能保证重传给当前组件的props是有变化的,所以在此方法中根据nextProps和this.props来查明重传的props是否改变,以及如果改变了要执行啥,比如根据新的props调用this.setState出发当前组件的重新render

2. shouldComponentUpdate(nextProps, nextState)
- 此方法通过比较nextProps,nextState及当前组件的this.props,this.state,返回true时当前组件将继续执行更新过程,返回false则当前组件更新停止,以此可用来减少组件的不必要渲染,优化组件性能。ps:这边也可以看出,就算componentWillReceiveProps()中执行了this.setState,更新了state,但在render前(如shouldComponentUpdate,componentWillUpdate),this.state依然指向更新前的state,不然nextState及当前组件的this.state的对比就一直是true了。

3. componentWillUpdate(nextProps, nextState)
- 此方法在调用render方法前执行,在这边可执行一些组件更新发生前的工作,一般较少用。

4. render
- render方法在上文讲过,这边只是重新调用。

5. componentDidUpdate(prevProps, prevState)
- 此方法在组件更新后被调用,可以操作组件更新的DOM,prevProps和prevState这两个参数指的是组件更新前的props和state
- 优化弊端

浅浅77
5楼 · 2021-02-02 09:42

在Vue中,生命周期和钩子函数是两个重要的概念。

通常在开发过程中,不了解这两个概念也可以完成基本的开发任务。

学习生命周期有两个目的:解决问题bug,对其他功能的完善和分析(时间节点)。

在Vue实例对象创建并完成Dom渲染过程中,不同时期会生成不同的事件,对应着不同的方法和回调函数。

以下是八个具体的过程:beforeCreate/created/beforeMount/mounted/beforeUpdate/updated/beforeDestory/destryed.

 

每一个过程的流程和具体的执行时间如下:

beforeCreate:function(){}//组件实例化之前执行的函数created:function(){}//组件实例化完毕,但是页面没有显示beforeMount:function(){}//组件挂载前,页面还没有展示,但是虚拟的DOM已经配置mounted:function(){}//组件挂载后,这个方法执行后,页面显示beforeUpdate:function(){}//当页面操作后,组件更新前,页面没有显示,此时虚拟DOM已经挂载updated:function(){}//组件更新完毕,页面已经显示beforeDestroy:function(){}//组件销毁之前destroyed:function(){}//组件销毁之后

这八个基本的方法在Vue实例组件进行渲染的过程中不断执行,在代码调试过程中很重要。

2020-01-09 更新

生命周期函数对应组件的不同阶段,可以处理对应的数据和请求。通常,在组件首次加载后发出请求,组件更新之前和组件更新之后,避免大量修改状态,否则会造成内存泄漏;在组件销毁之前判断数据是否保存;在组件销毁之后可以清理定时器和事件监听。

VUE 的生命周期函数和 React 的生命周期函数大同小异,下面简单列举 React 的生命周期函数

constructor(props) {super(props);this.val = props.val;this.state = {isOpen: false};}componentWillMount() {// 服务器端处理}componentDidMount() {// 页面加载完成,可以发出异步请求}componentWillUpdate() {// 组件将要更新}componentDidMount() {// 组件已经更新}componentWillReceiveProps() {// 组件将要接受到props(即将废弃)}shouldComponentUpdate() {// 组件是否更新}componentWillUnmount() {// 组件即将卸载}


小磊子
6楼 · 2021-02-02 10:16

1. 挂载卸载过程

1.1.constructor()

constructor()中完成了React数据的初始化,它接受两个参数:props和context,当想在函数内部使用这两个参数时,需使用super()传入这两个参数。
注意:只要使用了constructor()就必须写super(),否则会导致this指向错误。

1.2.componentWillMount()

componentWillMount()一般用的比较少,它更多的是在服务端渲染时使用。它代表的过程是组件已经经历了constructor()初始化数据后,但是还未渲染DOM时。

1.3.componentDidMount()

组件第一次渲染完成,此时dom节点已经生成,可以在这里调用ajax请求,返回数据setState后组件会重新渲染

1.4.componentWillUnmount ()

在此处完成组件的卸载和数据的销毁。

  1. clear你在组建中所有的setTimeout,setInterval

  2. 移除所有组建中的监听 removeEventListener

  3. 有时候我们会碰到这个warning:

Can only update a mounted or mounting component. This usually      means you called setState() on an unmounted component. This is a   no-op. Please check the code for the undefined component.

原因:因为你在组件中的ajax请求返回setState,而你组件销毁的时候,请求还未完成,因此会报warning
解决方法:

componentDidMount() {
    this.isMount === true
    axios.post().then((res) => {
    this.isMount && this.setState({   // 增加条件ismount为true时
      aaa:res    })})}componentWillUnmount() {
    this.isMount === false}

2. 更新过程

2.1. componentWillReceiveProps (nextProps)

  1. 在接受父组件改变后的props需要重新渲染组件时用到的比较多

  2. 接受一个参数nextProps

  3. 通过对比nextProps和this.props,将nextProps的state为当前组件的state,从而重新渲染组件

  componentWillReceiveProps (nextProps) {
    nextProps.openNotice !== this.props.openNotice&&this.setState({
        openNotice:nextProps.openNotice    },() => {
      console.log(this.state.openNotice:nextProps)
      //将state更新为nextProps,在setState的第二个参数(回调)可以打         印出新的state
  })}

2.2.shouldComponentUpdate(nextProps,nextState)

  1. 主要用于性能优化(部分更新)

  2. 唯一用于控制组件重新渲染的生命周期,由于在react中,setState以后,state发生变化,组件会进入重新渲染的流程,在这里return false可以阻止组件的更新

  3. 因为react父组件的重新渲染会导致其所有子组件的重新渲染,这个时候其实我们是不需要所有子组件都跟着重新渲染的,因此需要在子组件的该生命周期中做判断

2.3.componentWillUpdate (nextProps,nextState)

shouldComponentUpdate返回true以后,组件进入重新渲染的流程,进入componentWillUpdate,这里同样可以拿到nextProps和nextState。

2.4.componentDidUpdate(prevProps,prevState)

组件更新完毕后,react只会在第一次初始化成功会进入componentDidmount,之后每次重新渲染后都会进入这个生命周期,这里可以拿到prevProps和prevState,即更新前的props和state。

2.5.render()

render函数会插入jsx生成的dom结构,react会生成一份虚拟dom树,在每一次组件更新时,在此react会通过其diff算法比较更新前后的新旧DOM树,比较以后,找到最小的有差异的DOM节点,并重新渲染。

3. React新增的生命周期(个人补充)

React新增生命周期

3.1. getDerivedStateFromProps(nextProps, prevState)

代替componentWillReceiveProps()。
老版本中的componentWillReceiveProps()方法判断前后两个 props 是否相同,如果不同再将新的 props 更新到相应的 state 上去。这样做一来会破坏 state 数据的单一数据源,导致组件状态变得不可预测,另一方面也会增加组件的重绘次数。
举个例子:

// beforecomponentWillReceiveProps(nextProps) {
  if (nextProps.isLogin !== this.props.isLogin) {
    this.setState({ 
      isLogin: nextProps.isLogin,   
    });
  }
  if (nextProps.isLogin) {
    this.handleClose();
  }}// afterstatic getDerivedStateFromProps(nextProps, prevState) {
  if (nextProps.isLogin !== prevState.isLogin) {
    return {
      isLogin: nextProps.isLogin,
    };
  }
  return null;}componentDidUpdate(prevProps, prevState) {
  if (!prevState.isLogin && this.props.isLogin) {
    this.handleClose();
  }}

这两者最大的不同就是:
在 componentWillReceiveProps 中,我们一般会做以下两件事,一是根据 props 来更新 state,二是触发一些回调,如动画或页面跳转等。

  1. 在老版本的 React 中,这两件事我们都需要在 componentWillReceiveProps 中去做。

  2. 而在新版本中,官方将更新 state 与触发回调重新分配到了 getDerivedStateFromProps 与 componentDidUpdate 中,使得组件整体的更新逻辑更为清晰。而且在 getDerivedStateFromProps 中还禁止了组件去访问 this.props,强制让开发者去比较 nextProps 与 prevState 中的值,以确保当开发者用到 getDerivedStateFromProps 这个生命周期函数时,就是在根据当前的 props 来更新组件的 state,而不是去做其他一些让组件自身状态变得更加不可预测的事情。

3.2. getSnapshotBeforeUpdate(prevProps, prevState)

代替componentWillUpdate。
常见的 componentWillUpdate 的用例是在组件更新前,读取当前某个 DOM 元素的状态,并在 componentDidUpdate 中进行相应的处理。
这两者的区别在于:

  1. 在 React 开启异步渲染模式后,在 render 阶段读取到的 DOM 元素状态并不总是和 commit 阶段相同,这就导致在
    componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM 元素状态是不安全的,因为这时的值很有可能已经失效了。

  2. getSnapshotBeforeUpdate 会在最终的 render 之前被调用,也就是说在 getSnapshotBeforeUpdate 中读取到的 DOM 元素状态是可以保证与 componentDidUpdate 中一致的。
    此生命周期返回的任何值都将作为参数传递给componentDidUpdate()。


ban_gank
7楼 · 2021-02-02 10:47

实例化

  • constructor//构造函数:获取props,然后state, 

  • componentWillMount//挂载之前,可修改setState

  • render//渲染真实dom

  • componentDidMount//第一次render后,仅一次,可setState

存在期

  • componentWillReceiveProps(nextprops)//父组件render时props更新时,不管props是否变化

  • shouldComponentUpdate//修改state后自动调用,默认返回true,false跳过后面的,少用

  • componentWillUpdate//修改state后的render之前自动调用,相似于CWM

  • render

  • componentDidUpdate//render后调用,万不得已不要修改state死循环

销毁期

  • componentWillUnmount//销毁前

更改state 

  • this.setState((prevState,props)=>{    return { }    
    }
    ,callback)

 setTimeout

let this.idInterval =setInterval()

clearInterval(this.idInterval)


aijingda
8楼 · 2021-02-02 11:18

“钩子”就是在某个阶段给你一个做某些处理的机会。生命周期钩子函数就是在组件预备、创建、使用和销毁的过程中的函数监听。

React 组件生命周期:

componentWillMount :在渲染前调用,在客户端也在服务端。

componentDidMount:在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。

componentWillReceiveProps:在组件接收到一个新的prop时被调用。这个方法在初始化render时不会被调用。

shouldComponentUpdate:返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用,可以在你确认不需要更新组件时使用。

componentWillUpdate:在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。

componentDidUpdate:在组件完成更新后立即调用。在初始化时不会被调用。

componentWillUnmount:在组件从 DOM 中移除的时候立刻被调用。

R了个C
9楼 · 2021-02-02 11:44

componentWillMount() 组件挂载之前
在组件挂载之前调用且全局只调用一次。如果在这个钩子里可以setState,render后可以看到更新后的state,不会触发重复渲染。该生命周期可以发起异步请求,并setState。(React v16.3后废弃该生命周期,可以在constructor中完成设置state)

render() 渲染组件
render是一个React组件必须定义的生命周期,用来渲染dom。⚠️不要在render里面修改state,会触发死循环导致栈溢出。render必须返回reactDom

componentDidMount() 组件挂载完成后
在组件挂载完成后调用,且全局只调用一次。可以在这里使用refs,获取真实dom元素。该钩子内也可以发起异步请求,并在异步请求中可以进行setState。

componentWillReceiveProps (nextProps ) props即将变化之前
props发生变化以及父组件重新渲染时都会触发该生命周期,在该钩子内可以通过参数nextProps获取变化后的props参数,通过this.props访问之前的props。该生命周期内可以进行setState。(React v16.3后废弃该生命周期,可以用新的周期 static getDerivedStateFromProps 代替)

shouldComponentUpdate(nextProps, nextState) 是否重新渲染
组件挂载之后,每次调用setState后都会调用shouldComponentUpdate判断是否需要重新渲染组件。默认返回true,需要重新render。返回false则不触发渲染。在比较复杂的应用里,有一些数据的改变并不影响界面展示,可以在这里做判断,优化渲染效率

componentWillUpdate(nextProps, nextState)
shouldComponentUpdate返回true或者调用forceUpdate之后,componentWillUpdate会被调用。不能在该钩子中setState,会触发重复循环。(React v16.3后废弃该生命周期,可以用新的周期 getSnapshotBeforeUpdate )

componentDidUpdate() 完成组件渲染
除了首次render之后调用componentDidMount,其它render结束之后都是调用componentDidUpdate。该钩子内setState有可能会触发重复渲染,需要自行判断,否则会进入死循环。

componentWillUnmount() 组件即将被卸载
组件被卸载的时候调用。一般在componentDidMount里面注册的事件需要在这里删除。


相关问题推荐

  • 回答 120

    相对前几年来说,要高上不少了,毕竟入行的人也是越来越多了,基础的工作对应想要参与的人群基数越来越大,但是对于高端人才的需求还是很多,人才还是相对稀缺性的。所以,想要学web或者其他技术也一样,别等,别观望。web前端就业方向特别多包括web前端开发...

  • 回答 25

    相对定位和绝对定位是定位的两种表现形式,区别如下:一、主体不同1、相对定位:是设置为相对定位的元素框会偏移某个距离。2、绝对定位:absolute 脱离文档流,通过 top,bottom,left,right 定位。二、特点不同1、相对定位:在使用相对定位时,无论是否进行移...

  • 抓包是什么意思?2020-04-01 17:36
    回答 7
    已采纳

    抓包(packet capture)就是将网络传输发送与接收的数据包进行截获、重发、编辑、转存等操作,也用来检查网络安全。抓包也经常被用来进行数据截取等。抓包可以通过抓包工具来查看网络数据包内容。通过对抓获的数据包进行分析,可以得到有用的信息。目前流行的...

  • 回答 89

    常用的前端框架有Bootstrap框架、React框架、Vue框架、Angular框架、Foundation框架等等

  • 回答 65
    已采纳

    前端是目的就业前景非常不错的一个计算机技术,但是自学的话还是有一定难度的,网络上自学是碎片化的,同时互联网技术跟新换代快,自己的话比较吃力也学习不到最新的技术。

  • SSR 是什么意思?2020-03-20 18:56
    回答 6

    SSR就是一台服务器,可以利用 SSR 在远程的服务器上配置 SSR,使其能够成为 SSR 节点,这样本地电脑或者其它设备利用 SSR 节点实现 VPN 或者远程上网及游戏加速等方面。ShadowsocksR(简称 SSR)是 Shadowsocks 分支,在 Shadowsocks 的基础上增加了一些数据...

  • 回答 52
    已采纳

    计算机培训方向比较多,建议找适合自己的方向选择培训编程类:JAVA、WEB、Python、C/C++、C#等测试类:软件测试运维类:云计算、网络安全设计类:UI设计、3D建模等

  • 回答 11

    1、代码判断xAxis: {type: 'time',splitLine: {show: false},interval: 3600, // 设置x轴时间间隔axisLabel: {formatter: function(value, index) {return liangTools.unix2hm(value)}}},首先要把xAxis 显示类型设置成time,然后设置对应X轴......

  • 回答 8

    HTML5 + CSS + JavaScript 开发 跨平台重用代码 

  • 回答 4

    采用rem单位自动响应,并提供独有栅格化系统快速定义宽高、边距节省css代码量,同时总结各大型移动端网页,提供一套ui颜色搭配规范,尺寸规范,字体规范等。

  • 回答 10

    iView UI、ioni、SUI

  • 回答 6

     jQTouch 

  • 回答 4

    如果只是普通的移动端用vue react 或者dva 如果是要编译成小程序什么的或者混生 就用uni-app(对应vue语法)taro(对应react) 或者纯原生 这个没有限制的,自己怎么舒服怎么来

  • 回答 4

    因为可以运用在网页和小程序的开饭中,而且开源,用着便宜,企业都很喜欢

  • 回答 10

    一、Visual Studio Code下载地址:https://code.visualstudio.com/微软在2015年4月30日Build 开发者大会上正式宣布了 Visual Studio Code 项目:一个运行于 Mac OS X、Windows和 Linux 之上的,针对于编写现代 Web 和云应用的跨平台源代码编辑器。Visual Stud...

  • 回答 9

    jQuery自带淡入淡出效果 https://www.w3school.com.cn/jquery/jquery_fade.asp 看看这个 

没有解决我的问题,去提问