React 生命周期,对比vue学习

所谓生命周期就是代码被读取到的那一刻到页面渲染完成的历程

react 的生命周期相比较 vue 会显得复杂点

钩子链接: https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

 

整个过程被分成了三部分:挂载时更新时卸载时

1.挂载时

挂载时有个 constructor,这不是类中的构造器吗,然后 render 不是类编程中的函数吗,下面简单写一个类组件

import React, { Component } from 'react'

export default class Life extends Component {

  constructor () {
    super()
    console.log('组件开始加载');
    this.name = 'Dolphin'
  }

  componentDidMount() {
    console.log('组件挂载完成');
  }

  render() {
    console.log('组件开始被编译');
    return (
      <div>
        {this.name}
      </div>
    )
  }
}

挂载时:先执行 constructor ,此时就是获得数据源,再执行 render 渲染,编译得到虚拟 dom,中间穿插了个更新 DOMrefs最后执行 componentDidMount,这个 did 就是过去时,因此就是 vue 中的 onMounted,挂载完成。

更新 dom 不是生命周期,只是这个过程在这里发生

render 的目的是生成虚拟 dom,这个时候可以拿到 dom,但是值是空的,下面展示下,先引入 createRef 函数拿到 h4 的 dom,如下

import React, { Component, createRef } from 'react'

export default class Life extends Component {

  constructor () {
    super()
    console.log('组件开始加载', this.ref);
    this.name = 'Dolphin'
    this.ref = createRef() // 存放dom
  }

  componentDidMount() {
    console.log('组件挂载完成', this.ref);
  }

  render() {
    console.log('组件开始被编译', this.ref);
    return (
      <div>
        <h4 ref={this.ref}>{this.name}</h4>
      </div>
    )
  }
}

这就有点像是 vue 中的 beforeMount,均拿不到 dom

因此接口请求我们一般写在挂载完成 componentDidMount 中,因为有时候接口请求速度很快,会出现数据拿到了,但是 dom 还没渲染完成,若接口请求还想要操作 dom,就会失败,为了更好的操作 dom,请求我们写在挂载完成后

2. 更新时

更新阶段的 New props 就是拿到父组件传递过来的值setState 是自身数据源的改变forceUpdate 也是数据更新的方法,这是强制更新,这三个都会再一次触发 render,渲染完后又是更新 dom,最后又是更新 componentDidUpdate

因此更新阶段的钩子就只有两个,一个 render,一个 componentDidUpdate

刚刚上面的我改下,添加一个 setState,就是响应式更改数据源,那就一定会重新触发 rendercomponentDidUpdate

import React, { Component, createRef } from 'react'

export default class Life extends Component {

  constructor () {
    super()
    this.ref = createRef() // 存放dom
    this.state = {
        count: 1
    }
  }

  handleClick = () => {
    this.setState({
        count: this.state.count + 1
    })
  }

  componentDidUpdate() {
    console.log('组件更新完成');
  }

  render() {
    console.log('组件开始被编译', this.ref);
    return (
      <div>
        <h4 ref={this.ref} onClick={() => this.handleClick()}>{this.state.count}</h4>
      </div>
    )
  }
}

其实 react 中并没有说响应式这个概念,他就是原生 js,setState 是在数据更新时劫持了这个数据,setState 可以帮我们触发 render,更新视图,若不用 setState,数据是能照常更改,只是视图没有更新罢了

触发 render 操作的还有个 forceUpdate,这是强制更新,我们可以不用 setState 来改,如下

import React, { Component, createRef } from 'react'

export default class Life extends Component {

  constructor () {
    super()
    this.ref = createRef() 
    this.count = 1
  }

  handleClick = () => {
    this.count++
    this.forceUpdate() // 强制render重新调用
  }

  componentDidUpdate() {
    console.log('组件更新完成');
  }

  render() {
    console.log('组件开始渲染', this.ref);
    return (
      <div>
        <h4 ref={this.ref} onClick={() => this.handleClick()}>{this.count}</h4>
      </div>
    )
  }
}

在某些场景下,我们需要用 forceUpdate 来进行强制更新的

组件更新完成在 react 中只有一个 componentDidUpdate,而 vue 中就是 beforeUpdateupdated其实 react 中的 render 就是充当了 beforeUpdate

3.卸载时

就一个钩子 componentWillUnmount,组件卸载时执行

componentWillUnmount () {
	console.log('组件即将卸载');
}

4.总结

挂载时

  1. constructor:类中的构造器充当了生命周期,此时拿到数据源
  2. render:相当于vue中的 beforeMount,还拿不到 dom
  3. componentDidMount:挂载完成,可以拿到 dom

更新时

  1. render父组件传参 New props,修改数据源 setState,强制更新 forceUpdated 都会重新渲染 render
  2. componentDidUpdate:更新完成

卸载时

  1. componentWillUnmount:组件即将卸载时执行

5. 不常用的生命周期函数

常用的就是上面五个生命周期函数 constructorrendercomponentDidMountcomponentDidUpdate 和 componentWillUnmount,不常用的还有,如图,我把不常用的也展开来

 

static getDerivedStateFromProps()

这是个静态方法,因此这个生命周期函数只能在类组件中使用,这个方法比较冷门,它在render前调用,自行查看罕见用例

shouldComponentUpdate()

这个生命周期函数表示组件该不该更新,若里面返回 false,就不会给你更新视图,但是数据照常更新

import React, { Component, createRef } from 'react'

export default class Life extends Component {

  constructor () {
    console.log('组件开始加载');
    super()
    this.ref = createRef() // 存放dom
    this.state = {
        count: 1
    }
  }

  handleClick = () => {
    this.setState({
        count: this.state.count + 1
    })
    console.log(this.state.count);
  }

  shouldComponentUpdate() {
    return false
  }

  render() {
    console.log('组件开始渲染', this.ref);
    return (
      <div>
        <h4 ref={this.ref} onClick={() => this.handleClick()}>{this.state.count}</h4>
      </div>
    )
  }
}

打印下 count 的值,发现确实变化了,但是视图没有更新

getSnapshotBeforeUpdate()

这个函数返回的值会给到 componentDidUpdate,它在最近一个渲染输出后调用,也就是 render 完之后立马调用

这么看 react 的生命周期函数总共也就是 8 个,和 vue 的生命钩子数量差不多

参考文章:https://juejin.cn/post/7359821247675596835
 

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值