react 的生命周期分为3个阶段:分别是挂载,运行中(渲染),和卸载
1.1 构造函数 constructor()
完成数据初始化,接受两个参数 props (传入的属性) 和 context(上下文对象),当在函数内部使用这两个参数必须使用 super(props, context)
注意: 只要使用了constructor()就必须写super(),否则会导致this指向错误
1.2 componentWillMount()
在组件 constructor() 执行完成后执行,数据已经初始化完,但是还没渲染DOM。 很少用,一般用于服务器端渲染
1.3 componentDidMount()
time: 组件第一次渲染完成后,此时DOM节点已经生成。只会初次渲染进入一次。后续更新进入componentDidUpate生命周期
when: 调用 ajax ,使用 setSate 更细元素
1.4 componentWillUnmount()
time:组件将要卸载
when: 组件卸载,数据销毁。【1. 移除定时器,2. 清除事件removeEventListener, 3. 还原标志位】
2.1 componentWillReceiveProps(nextProps)
time: 当父组件传入的属性值发生变化时触发
args: nextProps 更新后的props, this.props是旧的props
通过意义示例来演示 componentWillReceiveProps 的触发
when: 当 props 传入的属性发生改变后,需要做其他业务逻辑时。 类似于 Vue 中的监听父组件传给子组件的值。
一般用于更新自己的state,或页面跳转。
// parent.js 中 import React from ‘react‘; import Children from ‘./children‘ class Parent extends React.Component { constructor (props) { super(props) this.state = { comment: "我是父组件中的state数据" } this.changeComment = this.changeComment.bind(this) } render () { return ( <div> 我是父组件 <button onClick={this.changeComment}>改变父组件传入子组件的属性</button> <Children comment={this.state.comment} /> </div> ) } // 通过点击事件改变父组件传给子组件的属性值 changeComment () { this.setState((state) => ({ comment: "属性发生了改变" })) } } export default Parent ----------------------------------------------------------------------- // children.js import React from ‘react‘; class Children extends React.Component { constructor (props, context) { super(props, context) this.state = { } } // 当父组件中点击按钮更新属性时,改方法触发 componentWillReceiveProps (nextProps) { console.log(nextProps, "新的props") console.log(this.props, "旧的props") } render () { return ( <div> <hr /> 我是子组件 <div> 我是父组件state传递过来的数据: {this.props.comment} </div> </div> ) } } export default Children
2.2 shouldComponentUpdate(nextProps,nextState)
args: nextProps 更新后的属性。nextSatte 更新后的 state
time: 组件要更新时触发。控制组件重新渲染,例如 setState 时,会触发组件重新渲染。在此 return false 会阻止组件重新渲染。
when: react 中父组件更新会导致子组件更新,当父组件更新,不需要更新某些子组件时,在这里处理。【主要用于性能优化】
// 组件更新时触发 shouldComponentUpdate (nextProps, nextState) { console.log(nextProps, nextState, "更新后的属性,状态") return false // return true 时会触发更新, return false时,子组件不会更新 }
2.3 componentWillUpdate(nextProps, nextState)
args: nextProps 更新后的属性。nextSatte 更新后的 state
time: 当shouldComponentUpdate生命周期 return true 时触发,组件进入重新渲染状态
when: 一般读取当前某个 DOM 元素的状态,并在 componentDidUpdate 中进行相应的处理。react 开启异步渲染时,componentWillUpdate获取到的DOM状态不可靠
2.4 componentDidUpdate(prevProps, prevState)
args: prevProps 更新前的属性,prevState 更新前的状态
time: 组件每次重新渲染的时候触发
when: 组件更新完成后,需要处理的逻辑放在这里
2.5 render()
time: 此阶段 jsx 生成 dom。在此react会通过其diff算法比较更新前后的新旧DOM树,比较以后,找到最小的有差异的DOM节点,并重新渲染
3.1 getDerivedStateFromProps(nextProps, prevState)
1. 代替componentWillReceiveProps(nextProps)
2. 对比:
1. componentWillReceiveProps(nextProps) 通过对比 this.props 和 props 更新自身的 state 状态。弊端:1. 破坏state数据的单一源。2. 增加页面重绘次数
2. getDerivedStateFromProps(nextProps, prevState) 强制要求对比 nextProps 和 prevState 来更新自身 state。不能访问 this.props
// before componentWillReceiveProps(nextProps) { if (nextProps.isLogin !== this.props.isLogin) { this.setState({ isLogin: nextProps.isLogin, }); } if (nextProps.isLogin) { this.handleClose(); } } // after static 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(); } }
3.2 getSnapshotBeforeUpdate(prevProps, prevState)
1. 代替 componentWillUpdate
2. 对比:
1. React 开启异步渲染模式后,在 render 阶段读取到的 DOM 元素状态并不总是和 commit 阶段相同,导致 componentDidUpdate 中使用 componentWillUpdate中读取到的 DOM 元素状态是不安全的,因为这时的值很有可能已经失效了
2. getSnapshotBeforeUpdate 会在最终的 render 之前被调用。也就是说在 getSnapshotBeforeUpdate 中读取到的 DOM 元素状态是可以保证与 componentDidUpdate 中一致的。此生命周期返回的任何值都将作为参数传递给componentDidUpdate()
原文:https://www.cnblogs.com/monkey-K/p/13036438.html