首页 > 其他分享 >react生命周期(详细版)

react生命周期(详细版)

时间:2022-11-04 11:37:37浏览次数:50  
标签:生命周期 render react state 调用 详细 props 组件

首先生命周期分为三个阶段:

    挂载:已经插入真实dom

    渲染(更新):正在被重新渲染

    卸载:已经移出真实dom

一、挂载:在组件实例被创建并插入到dom中时,生命周期调用顺序如下

旧生命周期:

1.constructor(props)
2.componentWillMount()-------------可以用但是不建议使用
3.render()
4.componentDidMount()

新生命周期:

constructor(props)
static getDerivedStateFromProps(props,state)--替代了componentWillReceiveProps
render()
componentDidMount()

(1)constructor

使用场景:
一般在 constructor 中做一些组件的初始化工作,例如:初始化组件的 state。

该方法只会执行一次,调用该方法会返回一个组件实例。
在初始化阶段执行,可直接对 this.state 赋值。其他生命周期函数中只能通过 this.setState 修改 state,不能直接为 this.state 赋值。

接收props和context,当想在函数内使用这两个参数需要在super传入参数,当使用constructor时必须使用super,否则可能会有this的指向问题,如果不初始化state或者不进行方法绑定,则可以不为组件实现构造函数;

避免将 props 的值复制给 state!这是一个常见的错误:

constructor(props) {
 super(props);
 // 不要这样做
 this.state = { color: props.color };
}

如此做毫无必要(可以直接使用 this.props.color),同时还产生了 bug(更新 prop 中的 color 时,并不会影响 state)

(2)componentWillMount

在组件挂载至 DOM 之前调用,并且只会调用一次。它在 render 方法之前调用,因此在 componentWillMount 中调用 this.setState 不会触发额外的渲染。
这个生命周期钩子使用频率较小,因为我们一般在 constructor 中初始化 state,在 componentDidMount 中引入副作用或者订阅内容。

(3)getDerivedStateFromProps

从props获取state。
它是一个静态方法,接收 propspropsprops 和 statestatestate 两个参数。它会在调用 render 方法之前被调用,不管是在初始挂载时还是在后续组件更新时都会被调用。
它的调用时机和 componentWillMount、componentWillUpdate、componentWillReceiveProps 一样都是在 render 方法被调用之前,它可以作为 componentWillMount、componentWillUpdate 和 componentWillReceiveProps 的替代方案。
当然,它的作用不止如此,它可以返回一个对象,用来更新 state,就像它的名字一样,从 props 中获取衍生的 state。如果不需要更新 state 则可以返回 null。
需要注意的是:这个生命周期函数是类的静态方法,并不是原型中的方法,所以在其内部使用 this 访问到的不是组件实例。
此生命周期钩子不常用,如果可以的话,我们也尽可能不会使用它。

static getDerivedStateFromProps(nextProps, prevState) {
    const {type} = nextProps;
    // 当传入的type发生变化的时候,更新state
    if (type !== prevState.type) {
        return {
            type,
        };
    }
    // 否则,对于state不进行任何操作
    return null;
}

(4)render

render 方法是类组件中唯一必须实现的方法,它的返回值将作为页面渲染的视图。render 函数应该为纯函数,也就是对于相同的 state 和 props,它总是返回相同的渲染结果。
render 函数被调用时,会返回以下四种类型之一:

React 元素:通常为 JSX 语法。例如:

、 等等。
数组或者 fragments:render 方法可以通过数组返回多个元素。
Portals:渲染子节点至不同的子树中。
字符串或者数值:会作为文本节点被渲染。
boolean 类型或者 null:什么都不渲染。
需要注意的是:如果 shouldComponentUpdate 生命周期钩子返回 false,则 render 方法(render 阶段后续生命周期钩子)不会执行。

(5)componentDidMount

在组件挂在后(插入到dom树中)后立即调用.

该生命周期方法会在组件挂载之后执行,也只会执行一次,也就是将组件对应的 DOM 插入 DOM 树中之后调用。它会在浏览器更新视图之前调用,如果在 componentDidMount 中直接调用 this.setState,它会触发额外的渲染,会再一次调用 render 函数,但是浏览器中视图的更新只会执行一次。
可以在这里调用Ajax请求,返回的数据可以通过setState使组件重新渲染,或者添加订阅,但是要在conponentWillUnmount中取消订阅

二、更新:当组件的 props 或 state 发生变化时会触发更新。

旧生命周期:

  1. componentWillReceiveProps (nextProps)------------------可以用但是不建议使用shouldComponentUpdate(nextProps,nextState)
  2. componetnWillUpdate(nextProps,nextState)----------------可以用但是不建议使用
  3. render()
  4. componentDidUpdate(prevProps,precState,snapshot)

新生命周期:

  1. static getDerivedStateFromProps(nextProps, prevState)
  2. shouldComponentUpdate(nextProps,nextState)
  3. render()
  4. getSnapshotBeforeUpdate(prevProps,prevState)
  5. componentDidUpdate(prevProps,precState,snapshot)

(1)componentWillReceiveProps ()

在已挂载组件接收到新的 props 之前调用。你可以在这个函数中比较新旧 props,并根据新旧 props 更改 state。但是它会破坏 props 数据的单一数据源。

在首次渲染组件时,不会调用此生命周期钩子;使用 this.setState 触发组件更新时,也不会调用此生命周期钩子。

不过要注意:如果是父组件渲染导致了组件的重新渲染,即使传给该组件的 props 没变,该组件中的这个生命周期函数也会被调用。
我们一般不使用此生命周期函数,因为它通常会破坏数据源的单一性。

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

(2)shouldComponentUpdate

在渲染之前被调用,默认返回为true。

熟悉 React 组件生命周期的话都知道:调用 setState 方法总是会触发 render 方法从而进行 vdom re-render 相关逻辑,哪怕实际上你没有更改到 Component.state

this.state = {count: 0}
this.setState({count: 0});// 组件 state 并未被改变,但仍会触发 render 方法
为了避免这种性能上的浪费, React 提供了一个 shouldComponentUpdate 来控制触发 vdom re-render 逻辑的条件。于是 PureRenderMixin 作为一种优化技巧被使用。它仅仅是浅比较对象,深层次的数据结构根本不管用
在组件准备更新之前调用,但是首次渲染或者使用 forceUpdate 函数时不会被调用。跟它的名字一样,它用来判断一个组件是否应该更新。

默认情况下,当组件的 props 或者 state 变化时,都会导致组件更新。它在 render 方法之前执行,如果它的返回值为 false,则不会更新组件,也不会执行后面的 render 方法。

它接收两个参数,nextProps 和 nextState,即下一次更新的 props 和下一次更新的 state。我们可以将 this.props 和 nextProps 比较,以及将 this.state 与 nextState 比较,并返回 false,让组件跳过更新。不过注意:它并不会阻止子组件因为 state 改变而导致的更新。
使用场景:
这个生命周期方法通常用来做性能优化。也可以继承pureComponent来性能优化
image

(3)componentWillUpdate

当组件接收到新的props和state会在渲染前调用,初始渲染不会调用该方法。

shouldComponentUpdate返回true以后,组件进入重新渲染的流程,进入componentWillUpdate,不能在这使用setState,在函数返回之前不能执行任何其他更新组件的操作

此方法可以替换为 componentDidUpdate()。如果你在此方法中读取 DOM 信息(例如,为了保存滚动位置),则可以将此逻辑移至 getSnapshotBeforeUpdate() 中。

(4)getSnapshotBeforeUpdate

在最后一次渲染(提交到dom节点)之前调用,替换componetnWillUpdate
此生命周期函数在最近一次渲染提交至 DOM 树之前执行,此时 DOM 树还未改变,我们可以在这里获取 DOM 改变前的信息,例如:更新前 DOM 的滚动位置。
它接收两个参数,分别是:prevProps、prevState,上一个状态的 props 和上一个状态的 state。它的返回值将会传递给 componentDidUpdate 生命周期钩子的第三个参数。
使用场景:
需要获取更新前 DOM 的信息时。例如:需要以特殊方式处理滚动位置的聊天线程等。

(5)componentDidUpdate:在更新之后立即调用,首次渲染不会调用,之后每次重新渲染都会被调用。

可以在该方法调用setState,但是要包含在条件语句中,否则一直更新会造成死循环

当组件更新后,可以在此处对 DOM 进行操作。如果对更新前后的props进行了比较,可以进行网络请求。(当 props 未发生变化时,则不会执行网络请求)。

componentDidUpdate(prevProps) {
  // 典型用法(不要忘记比较 props):
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}

如果组件实现了 getSnapshotBeforeUpdate() 生命周期(不常用),则它的返回值将作为 componentDidUpdate() 的第三个参数 “snapshot” 参数传递。否则此参数将为 undefined。如果返回false就不会调用这个函数。

三、卸载:当组件从 DOM中移除时会调用如下方法:

(4)新旧生命周期相同:componentWillUnmount():

在组件卸载和销毁之前调用

在这执行必要的清理操作,例如,清除timer(setTimeout,setInterval),取消网络请求,或者取消在componentDidMount的订阅,移除所有监听

标签:生命周期,render,react,state,调用,详细,props,组件
From: https://www.cnblogs.com/coderz1/p/16857159.html

相关文章

  • 细说React组件性能优化
    React组件性能优化最佳实践React组件性能优化的核心是减少渲染真实DOM节点的频率,减少VirtualDOM比对的频率。如果子组件未发生数据改变不渲染子组件。组件卸载前......
  • React-Hook最佳实践
    ReactHook新出现背景类组件的问题复用组件状态难,高阶组件+渲染属性providerscustomers,等一堆工具都是为了解决这个问题,但是造成了很严重的理解成本和组件嵌套地狱......
  • 详解React的Transition工作原理原理
    Transition使用姿势Transition是react18引入的新概念,用来区分紧急和非紧急的更新。紧急的更新,指的是一些直接的用户交互,如输入、点击等;非紧急的更新,指的是UI界面......
  • 通俗易懂的React事件系统工作原理
    前言React为我们提供了一套虚拟的事件系统,这套虚拟事件系统是如何工作的,笔者对源码做了一次梳理,整理了下面的文档供大家参考。在React事件介绍中介绍了合成事件对象以......
  • 这可能是你需要的React实战技巧
    一、父组件通过Ref调用子组件中的方法这里同时演示使用函数组件和类组件的父子组件如何编写子组件React.forwardRefReact.useImperativeHandlepublic、private、pr......
  • React组件之间的通信方式总结(上)
    先来几个术语:官方我的说法对应代码ReactelementReact元素letelement=<span>A爆了</span>Component组件classAppextendsReact.Component{}无Ap......
  • 年前端react面试打怪升级之路
    react和vue的区别相同点:数据驱动页面,提供响应式的试图组件都有virtualDOM,组件化的开发,通过props参数进行父子之间组件传递数据,都实现了webComponents规范数据流动单......
  • 百度前端react面试题总结
    componentWillReceiveProps调用时机已经被废弃掉当props改变的时候才调用,子组件第二次接收到props的时候在调用setState之后发生了什么状态合并,触发调和:setState......
  • React组件之间的通信方式总结(下)
    一、写一个时钟用react写一个每秒都可以更新一次的时钟importReactfrom'react'importReactDOMfrom'react-dom'functiontick(){letele=<h1>{ne......
  • React组件基础
    1.组件基本介绍组件是React中最基本的内容,使用React就是在使用组件组件表示页面中的部分功能多个组件可以实现完整的页面功能组件特点:可复用,独立,可组合2.Re......