React之生命周期初步认识

React的生命周期和Vue的生命周期很多的相似部分,可以说是大致的结构都是类似的,下面我们先看看React中常用的生命周期图

  

1.constructor() 组件挂载之前调用的构造函数

  1)组件不需要为state赋予初始值或者不需要绑定事件的情况下不需要为组件添加构造函数或者不需要使用props中的值

  2)constructor()方法的基本使用

 constructor(props){
    super(props)
    //不要再此处调用setState方法
    this.state={
      count:1
    }
    handClick=()=>{
      this.setState({
        count:this.state.count++
      })
    }

  }

2.render() 组件中唯一必须实现的方法

  1)render函数应该保持是一个纯函数,在state不变的情况下,每次输出相同,render函数保持纯函数的好处是代码可读性更好

  2)如需与浏览器进行交互请在componentDidMount()中进行或者在其他生命周期函数中实现

3.componentDidMount() 组件挂载后(插入DOM树中调用)

  1)如需进行网络请求这里是个很好的时机

  2)此时适合添加订阅,添加完成订阅,记得在componentWillUnmount()取消订阅(此函数会在组件摧毁之前调用)

  3)可以在此调用setState()函数,state中的状态改变组件会再次render(),但会发生在屏幕变化之前,用户感觉不到两次render,但会存在性能问题,应在constructor中进行state初始化,但是页面的渲染依赖于后台请求的数据,你可以在这里处理

4.componentDidUpdate()更新之后执行的函数,首次渲染不会执行

  1)组件更新之后可以在此进行DOM操作

  2)在此调用setState函数必须加判断条件,不然会出现死循环

5.componentWillUnMount() 会在组件摧毁之前调用

  1)清除 timer,取消网络请求或清除在 componentDidMount() 中创建的订阅等

6.setState()虽然不是生命周期函数,但是它却在生命周期函数中有这很大的作用,所以我在这里一起介绍setState()函数

  1)setState函数在react中不是立即执行的,react会收集多次的setState一起执行,所以避免在设置setState之后立即使用state中的值,在这里react给出的两个解决方案是:

    setState函数添加一个回调函数和在componentDidUpdate()中执行之后的操作,官方更推荐在componentDidUpdate中执行

7.forceUpDate()

  1)组件在state和props变化时默认会重新渲染,但是如果render()依赖于其他数据我们可以调用forceUpDate强制渲染

  2)调用 forceUpdate() 将致使组件调用 render() 方法,此操作会跳过该组件的 shouldComponentUpdate()。但其子组件会触发正常的生命周期方法,包括 shouldComponentUpdate() 方法。如果标记发生变化,React 仍将只更新 DOM

  3)通常你应该避免使用 forceUpdate(),尽量在 render() 中使用 this.props 和 this.state

8.关于为什么react官方不建议在componentWillMount中执行ajax请求?

  1)ReactFiber引入了异步渲染,有了异步渲染之后,React组件的渲染过程是分时间片的,不是一口气从头到尾把子组件全部渲染完,而是每个时间片渲染一点,然后每个时间片的间隔都可去看看有没有更紧急的任务(比如用户按键),

如果有,就去处理紧急任务,如果没有那就继续照常渲染。根据ReactFiber的设计,一个组件的渲染被分为两个阶段:第一个阶段(也叫做render阶段)是可以被React打断的,一旦被打断,这阶段所做的所有事情都被废弃,当React处理完紧急的事情回来,依然会重新渲染这个组件,  

这时候第一阶段的工作会重做一遍;第二个阶段叫做commit阶段,一旦开始就不能中断,也就是说第二个阶段的工作会稳稳当当地做到这个组件的渲染结束。两个阶段的分界点,就是render函数。render函数之前的所有生命周期函数  

(包括render)都属于第一阶段,之后的都属于第二阶段。开启异步渲染,虽然我们获得了更好的感知性能,但是考虑到第一阶段的的生命周期函数可能会被重复调用,不得不对历史代码做一些调整 

 2)一个组件的componentWillMount比componentDidMount也早调用不了几微秒,性能没啥提高;而且,等到异步渲染开启的时候,componentWillMount就可能被中途打断,中断之后渲染又要重做一遍,  

想一想,在componentWillMount中做AJAX调用,代码里看到只有调用一次,但是实际上可能调用N多次,这明显不合适。

相反,若把AJAX放在componentDidMount,因为componentDidMount在第二阶段,所以绝对不会多次重复调用,这才是AJAX合适的位置

posted @ 2019-08-22 15:35  进击的白菜  阅读(183)  评论(0编辑  收藏  举报