React组件的生命周期深入理解分析

目录
  • 生命周期钩子(新)
  • 生命周期钩子(旧)
  • 父子组件生命周期

组件从创建到销毁的过程,被称为组件的生命周期。

在生命周期的各个阶段都有相对应的钩子函数,会在特定的时机被调用,被称为组件的生命周期钩子。

生命周期回调函数 = 生命周期钩子函数 = 生命周期函数 = 生命周期钩子

函数式组件没有生命周期,因为生命周期函数是 React.Component 类的方法实现的,函数式组件没有继承 React.Component,所以也就没有生命周期。

<-- 容器!-->
<div id="test"></div>
// 创建组件
class Life extends React.Component{
	state = {opacity:1}
	// 调用时机:组件挂载完毕
	componentDidMount(){
		this.timer = setInterval(() => {
			let {opacity} = this.state
			opacity -= 0.1
			if(opacity <= 0) opacity = 1
			this.setState({opacity})
		}, 200);
	}
	//调用时机:组件将要卸载
	componentWillUnmount(){
		clearInterval(this.timer)
	}
	handleUnmount = ()=>{
		//卸载组件
		ReactDOM.unmountComponentAtNode(document.getElementById('test'))
	}
	//调用时机:初始化渲染、状态更新之后
	render(){
		return(
			<div>
				<h2 style={{opacity:this.state.opacity}}>我是一段透明度会变化的文字</h2>
				<button onClick={this.handleUnmount}>点击卸载</button>
			</div>
		)
	}
}
//渲染组件
ReactDOM.render(<Life/>,document.getElementById('test'))

生命周期钩子(新)

新的生命周期钩子增加了 getDerivedStateFromProps 和 getSnapshotBeforeUpdate。

constructor():constructor() 构造函数在 React 组件挂载之前被调用。

如果不初始化 state 或不为事件处理函数绑定实例,则不需要写 constructor()。

不能在 constructor() 构造函数内部调用 this.setState(), 因为此时第一次 render() 还未执行,也就意味 DOM 节点还未挂载。

static getDerivedStateFromProps(nextProps, prevState):在每次调用 render() 方法之前都会被调用,在初始化和更新时都会被调用。

getDerivedStateFromProps() 第一个参数为即将更新的 props,第二个参数为上一个状态的 state,可以比较 props 和 state 来加一些限制条件,防止无用的 state 更新。

getDerivedStateFromProps() 的返回值是必须的。返回一个对象来更新 state,如果不需要更新,返回 null 即可。 getDerivedStateFromProps() 适用于 state 的值在任何时候都取决于 props 的情况。 getDerivedStateFromProps() 是一个静态函数,是放在组件身上的,而不是放在组件实例身上,因此不能使用 this。

// 之前使用 componentWillReceiveProps
componentWillReceiveProps(nextProps) {
    if (nextProps.location.search !== this.props.location.search) {
    	this.init()
    }
}
// 现在使用 getDerivedStateFromProps:相当于把 componentWillReceiveProps 拆分成 getDerivedStateFromProps 和 componentDidUpdate
static getDerivedStateFromProps(nextProps, prevState) {
  const {search} = nextProps.location
  if (search !== prevState.search) {
    return {
      search,
    }
  }
  return null
}
componentDidUpdate(prevProps, prevState) {
  const {search} = this.state
   if (search !== prevState.search) {
    this.init()
  }
}

render():render() 方法是类组件中唯一必须实现的方法,用于渲染 DOM,render() 方法必须返回 reactDOM。

在 render() 的 return 之前不能写 setState,否则会触发死循环导致内存崩溃;return 体里面是可以写的。

// Wrong
render(){
	this.setState({...})
	return (...)
}
// Correct
render(){
	return (
		<input onClick={()=>this.setState({...})} />
   )
}

componentDidMount():在组件挂载后 (插入 DOM 树后) 立即调用,此生命周期是发送网络请求、开启定时器、订阅消息等的好时机,并且可以在此钩子函数里直接调用 setState()。

shouldComponentUpdate(nextProps, nextState):在组件更新之前调用,可以控制组件是否进行更新, 返回 true 时组件更新, 返回 false 则不更新。不写此生命周期钩子时默认为 true。

shouldComponentUpdate() 第一个参数是即将更新的 props 值,第二个参数是即将更新后的 state 值,可以根据更新前后的 props 或 state 来比较加一些限制条件,决定是否更新,进行性能优化。

不要在 shouldComponentUpdate 中调用 setState(),否则会导致无限循环调用更新、渲染,直至浏览器内存崩溃。

getSnapshotBeforeUpdate(prevProps, prevState):在最新的渲染数据提交给 DOM 前会调用,也就是说,在 render 之后,在 componentDidUpdate 之前调用。使得组件可以在更新之前获取快照值。不常用。

它可以使组件在 DOM 真正更新之前捕获一些信息(例如滚动位置),此生命周期返回的任何值都会作为参数传递给 componentDidUpdate(),如不需要传递任何值,那么返回 null。返回值是必须的。

componentDidUpdate(prevProps, prevState, snapshot):componentDidUpdate() 会在更新后会被立即调用。首次渲染不会执行。

包含三个参数,第一个是上一次props值。 第二个是上一次state值,第三个是“snapshot” 参数传递。

可以进行前后 props 的比较进行条件语句的限制,来进行 setState() , 否则会导致死循环。

componentWillUnmount():componentWillUnmount() 在组件即将被卸载或销毁时进行调用。此生命周期是清理定时器、取消订阅等操作的好时机。

组件的挂载流程:

  • constructor
  • getDerivedStateFromProps
  • render
  • componentDidMount

setState 更新流程:

  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • getSnapshotBeforeUpdate
  • componentDidUpdate

组件的卸载流程: componentWillUnmount

生命周期钩子(旧)

React 从 v16.3 开始废弃 componentWillMount、componentWillReceiveProps、componentWillUpdate 三个钩子函数。在新版本中使用需要加上 UNSAFE_ 前缀,否则会触发控制台的警告。

UNSAFE 不是指安全性,而是表示使用这些生命周期的代码在 React 的未来版本中更有可能出现 Bug,尤其是在启用异步渲染之后。

组件的挂载流程:

  • constructor
  • componentWillMount
  • render
  • componentDidMount

setState 更新流程:

  • shouldComponentUpdate
  • componentWillUpdate(组件更新之前调用)
  • render
  • componentDidUpdate

forceUpdate 强制更新流程:

  • componentWillUpdate(组件更新之前调用)
  • render
  • componentDidUpdate

父组件 render 之后子组件的更新流程:

  • componentWillReceiveProps(子组件接收到新的 props 之前调用,第一次接收到 props 不会调用)
componentWillReceiveProps(nextProps) {
	// 可以和 this.props 中的数据进行对比,以决定是否要执行某些方法
}
  • shouldComponentUpdate
  • componentWillUpdate(组件更新之前调用)
  • render
  • componentDidUpdate

组件的卸载流程:

componentWillUnmount

父子组件生命周期

当子组件自身的 state 状态改变,不会对父组件产生副作用的情况下,父组件不会进行更新,也就是不会触发父组件的生命周期。

当父组件状态变化时(不会是否更改到传给子组件的 props),会触发自身和子组件对应的生命周期。

render 以及 render 之前的生命周期,父组件先执行;

render 之后的生命周期,子组件先执行,并且是与父组件交替执行。

父子组件初始化流程:

  • 父组件constructor
  • 父组件getDerivedStateFromProps
  • 父组件render
  • 子组件constructor
  • 子组件getDerivedStateFromProps
  • 子组件render
  • 子组件componentDidMount
  • 父组件componentDidMount

子组件修改自身的 state 状态流程:

  • 子组件getDerivedStateFromProps
  • 子组件shouldComponentUpdate
  • 子组件render
  • 子组件getSnapshotBeforeUpdate
  • 子组件componentDidUpdate

父组件修改 state 状态流程:

  • 父组件getDerivedStateFromProps
  • 父组件shouldComponentUpdate
  • 父组件render
  • 子组件getDerivedStateFromProps
  • 子组件shouldComponentUpdate
  • 子组件render
  • 子组件getSnapshotBeforeUpdate
  • 父组件getSnapshotBeforeUpdate
  • 子组件componentDidUpdate
  • 父组件componentDidUpdate

父组件卸载子组件:

// 通过点击父组件中的 [卸载 / 挂载子组件] 按钮来卸载子组件
handelToggle = () => {
    this.setState({
      isHidden: !this.state.isHidden
    })
  }
<button onClick={this.handelToggle}>挂载/卸载子组件</button>
{this.state.isHidden ? '' : <Child />>}
  • 父组件getDerivedStateFromProps
  • 父组件shouldComponentUpdate
  • 父组件render
  • 父组件getSnapshotBeforeUpdate
  • 子组件componentWillUnmount
  • 组件componentDidUpdate

父组件重新挂载子组件:

再次点击父组件中的 [卸载 / 挂载子组件] 按钮来挂载子组件。

  • 父组件getDerivedStateFromProps
  • 父组件shouldComponentUpdate
  • 父组件render
  • 子组件constructor
  • 子组件getDerivedStateFromProps
  • 子组件render
  • 父组件getSnapshotBeforeUpdate
  • 子组件componentDidMount
  • 父组件componentDidUpdate

到此这篇关于React组件的生命周期深入理解分析的文章就介绍到这了,更多相关React组件的生命周期内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 浅谈React Native 中组件的生命周期

    概述 就像 Android 开发中的 View 一样,React Native(RN) 中的组件也有生命周期(Lifecycle).所谓生命周期,就是一个对象从开始生成到最后消亡所经历的状态,理解生命周期,是合理开发的关键.RN 组件的生命周期整理如下图: 如图,可以把组件生命周期大致分为三个阶段: 第一阶段:是组件第一次绘制阶段,如图中的上面虚线框内,在这里完成了组件的加载和初始化: 第二阶段:是组件在运行和交互阶段,如图中左下角虚线框,这个阶段组件可以处理用户交互,或者接收事件更新界面: 第

  • React Class组件生命周期及执行顺序

    一.react组件的两种定义方式 1.函数组件,简单的函数组件像下面这样,接收Props,渲染DOM,而不关注其他逻辑 function Welcome(props) { return <h1>Hello, {props.name}</h1>; } 函数组件无法使用State,也无法使用组件的生命周期方法,没有this,纯展示型组件. 建议:在写组件时,先思考组件应不应该写成展示型组件,能写成展示型组件的尽量写成展示型. 2.class组件,需要继承React.Component,

  • 实例讲解React 组件生命周期

    在本章节中我们将讨论 React 组件的生命周期. 组件的生命周期可分成三个状态: Mounting:已插入真实 DOM Updating:正在被重新渲染 Unmounting:已移出真实 DOM 生命周期的方法有: componentWillMount 在渲染前调用,在客户端也在服务端. componentDidMount : 在第一次渲染后调用,只在客户端.之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问. 如果你想和其他JavaScript框架一起使

  • React组件生命周期详解

    调用流程可以参看上图. React组件提供了生命周期的钩子函数去响应组件不同时刻的状态,组件的生命周期如下: 实例化 存在期 销毁期 实例化 首次调用组件时,有以下方法会被调用(注意顺序,从上到下先后执行): getDefaultProps 这个方法是用来设置组件默认的props,组件生命周期只会调用一次.但是只适合react.createClass直接创建的组件,使用ES6/ES7创建的这个方法不可使用,ES6/ES7可以使用下面方式: //es7 class Component { stat

  • React 组件的常用生命周期函数汇总

    目录 1. 概述 2. 生命周期的三个阶段 2.1. 创建时(挂载阶段) 2.2. 更新时(更新阶段) 2.3. 卸载时(卸载阶段) 1. 概述 意义:组件的生命周期有助于理解组件的运行方式.完成更复杂的组件功能.分析组件错误原因等. 组件的生命周期:组件从被创建到挂载到页面中运行,再到组件不用时卸载的过程. 生命周期的每个阶段总是伴随着一些方法调用,这些方法就是生命周期的钩子函数. 钩子函数的作用:为开发人员在不同阶段操作组件提供了时机. 只有类组件才有生命周期. 2. 生命周期的三个阶段 每

  • React中的生命周期和子组件

    目录 组件生命周期 创建创建期 获取虚拟DOM 子组件 组件生命周期 为了说明组件的创建,存在,销毁的过程,react提供了组件的生命周期,共分三大周期: 创建期:说明组件的创建的过程,相当于人的少年 存在期:说明组件的存在的过程,相当于人的中年 销毁期:说明组件的销毁的过程,相当于人的老年 创建创建期 创建期共分五个阶段: ES5开发中,对应五个方法:getDefaultProps,getInitialsate, ​​componentWillMount​​, ​​render​​, ​​co

  • React组件的生命周期详细描述

    目录 一.什么是生命周期 二.装载过程 1.constructor 2.render 3.componentWillMount和componentDidMount 三.更新过程 1.componentWillReceiveProps(nextProps) 2.shouldComponentUpdate(nextProps, nextState) 3.componentWillUpdate和componentDidUpdate 4.触发render 四.卸载过程 五.生命周期流程 1.第一次初始化

  • React生命周期与父子组件间通信知识点详细讲解

    目录 声明周期 声明周期解析 生命周期函数 Constructor componentDidMount componentDidUpdate componentWillUnmount 不常用的生命周期函数 认识组件间的通信 参数propTypes 限制单个元素 默认 Prop 值 对于函数式组件 子组件传递父组件 声明周期 很多的事物都有从创建到销毁的整个过程,这个过程称之为是生命周期: React组件也有自己的生命周期,了解组件的生命周期可以让我们在最合适的地方完成自己想要的功能: 生命周期和

  • 老生常谈js-react组件生命周期

    组件的生命周期可分成三个状态: •Mounting:已插入真实 DOM •Updating:正在被重新渲染 •Unmounting:已移出真实 DOM 生命周期的方法有: •componentWillMount 在渲染前调用,在客户端也在服务端. •componentDidMount : 在第一次渲染后调用,只在客户端.之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问. 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeou

  • React组件的生命周期深入理解分析

    目录 生命周期钩子(新) 生命周期钩子(旧) 父子组件生命周期 组件从创建到销毁的过程,被称为组件的生命周期. 在生命周期的各个阶段都有相对应的钩子函数,会在特定的时机被调用,被称为组件的生命周期钩子. 生命周期回调函数 = 生命周期钩子函数 = 生命周期函数 = 生命周期钩子 函数式组件没有生命周期,因为生命周期函数是 React.Component 类的方法实现的,函数式组件没有继承 React.Component,所以也就没有生命周期. <-- 容器!--> <div id=&qu

  • Android编程中的四大基本组件与生命周期详解

    本文实例讲述了Android编程中的四大基本组件与生命周期.分享给大家供大家参考,具体如下: Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一:了解四大基本组件 Activity : 应用程序中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应. Activity之间通过Intent进行通信.在Intent 的描述结构中,有两个最

  • React State与生命周期详细介绍

    目录 一.State 1.1 类组件中的State 1.2 函数组件中的State 二.React生命周期 2.1 挂载 2.2 更新 2.3 卸载 2.4 函数式组件useEffect 三.总结 一.State 在React当中,当你更新组件的state,然后新的state就会重新渲染到页面中.在这个时候不需要你操作任何DOM.这和vue中组件的data中的数据是相似的. 1.1 类组件中的State <!DOCTYPE html> <html lang="en"&

  • React中的生命周期详解

    目录 react生命周期 常用的生命周期 不常用的生命周 完整的生命周期图 react生命周期 函数组件无生命周期,生命周期只有类组件才拥有 生命周期函数指在某一时刻组件会自动调用并执行的函数. React每个类组件都包含生命周期方法,以便于在运行过程中特定的阶段执行这些方法. 例如:我们希望在第一次将其呈现到DOM时设置一个计时器Clock.这在React中称为“安装”.我们也想在删除由产生 的DOM时清除该计时器Clock.这在React中称为“卸载”. 一般分为:挂载.更新.卸载 常用的生

  • 浅谈angular2 组件的生命周期钩子

    本文介绍了浅谈angular2 组件的生命周期钩子,分享给大家,具体如下: 按照生命周期执行的先后顺序,Angular生命周期接口如下所示 名称 时机 接口 范围 ngOnChanges 当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在 ngOnInit之前. OnChanges 指令和组件 ngOnInit 在第一轮 ngOnChanges 完成之后调用. ( 译注:也就是说当每个输入属性的值都被触发了一次 ngOnChanges之后才会调用 ngOnInit ,此时所有输入属性都已

  • vue同步父子组件和异步父子组件的生命周期顺序问题

    关于vue组件的引入方式有两种 一. 同步引入 例子: import Page from '@/components/page' 二.异步引入 例子:const Page = () => import('@/components/page') 或者: const Page = resolve => require(['@/components/page'], page) 两种引入方式的不同之处在于: 同步引入时生命周期顺序为:父组件的beforeMount.created.beforeMoun

  • 详解Angular组件之生命周期(二)

    一.view钩子 view钩子有2个,ngAfterViewInit和ngAfterViewChecked钩子. 1.实现ngAfterViewInit和ngAfterViewChecked钩子时注意事项 以父组件调用子组件方法中例子为基础,在父组件中实现ngAfterViewInit和ngAfterViewChecked钩子. 这两个钩子是在组件的模版所有内容组装完成后,组件模版已经呈现给用户看了,之后这两个钩子方法会被调用. @ViewChild('child1') child1:Child

随机推荐