React生命周期

栏目: IOS · Android · 发布时间: 5年前

内容简介:如果将组件比作我们图中的:ant:,吊绳比作:ant:(组件)的寿命,吊绳左端表示:ant:的出生(组件的创建),右端表示:ant:的死亡(组件的销毁)。:ant:从生到死的过程会触发吊牌上的钩子函数执行,在挂载:将虚拟DOM转化为真实DOM的过程组件挂载之前,在渲染过程中可能会执行多次,不推荐使用
React生命周期

前言

如果将组件比作我们图中的:ant:,吊绳比作:ant:(组件)的寿命,吊绳左端表示:ant:的出生(组件的创建),右端表示:ant:的死亡(组件的销毁)。:ant:从生到死的过程会触发吊牌上的钩子函数执行,在 React 中我们把组件从创建到销毁的过程中需要触发的钩子函数称之为生命周期函数

React 生命周期

旧版

React生命周期

初始化阶段( Initalization )

  • setup props ande state (设置组件的初始化属性和状态)

初始化状态对象

static defaultProps = {
    name:'计数器'  //初始化默认的属性对象
}
复制代码

初始化属性对象

constructor(props){
    super(props);
    this.state = {
        number:0
    }
}
复制代码

挂载阶段( Mounting )

挂载:将虚拟DOM转化为真实DOM的过程

componentWillMount

组件挂载之前,在渲染过程中可能会执行多次,不推荐使用

render

组件挂载

componentDidMount

组件挂载之后,永远只会执行一次,推荐在此阶段执行副作用,进行异步操作。比如发 ajax 请求,操作 DOM

更新阶段( Updation )

属性更新(props变化)

componentWillReceiveProps

组件收到新的属性对象时调用,首次渲染不会触发

shouldComponentUpdate

询问组件是否可以更新

  • 参数:新的属性对象
  • 返回: boolean
    true
    false
    

componentWillUpdate

组件更新之前

render

根据新的属性对象重新挂载(渲染)组件

componentDidUpdate

组件更新完成

状态更新(state变化)

shouldComponentUpdate

询问组件是否可以更新

  • 参数:新的状态对象
  • 返回: boolean
    true
    false
    

componentWillUpdate

组件更新之前

render

根据新的状态对象重新挂载(渲染)组件

componentDilUpdtae

组件更新完成

卸载阶段( Unmounting )

componentWillUnmount

组件卸载之前调用

放码过来

有兴趣的朋友可以根据以下代码进行测试

import React, { Component } from 'react';
/**
 * 父组件
 */
class Counter extends Component {
  static defaultProps = { //初始化默认的属性对象
    name:'计数器'
  }
  constructor(props) {
    super(props);
    this.state = { // 初始化默认的状态对象
      number:0
    }
    console.log('1. 父constructor初始化 props and state');
  }
  componentWillMount() {
    console.log('2. 父componentWillMount组件将要挂载');
  }
  componentDidMount() {
    console.log('4. 父componentDidMount组件挂载完成');
  }
  shouldComponentUpdate() {
    console.log('5. 父componentShouldUpdate询问组件是否可以更新');
    return true;
  }
  componentWillUpdate() {
    console.log('6. 父componentWillUpdate组件将要更新');
  }
  componentDidUpdate() {
    console.log('7. 父componentDidUpdate组件更新完成');
  }
  render() {
    console.log('3. 父render渲染,也就是挂载');
    const style = {display:'block'}
    return (
      <div style={{border:'10px solid green',pending:'10px'}}>
        {this.props.name}:{this.state.number}
        <button onClick={this.add} style={style}>+</button>
        {this.state.number %3 !== 0 && <SubCounter number={this.state.number}/>}
      </div>
    );
  }
  add = () => {
    this.setState({
      number:this.state.number+1
    })
  }
}
/**
 * 子组件
 */
class SubCounter extends Component {
  static defaultProps = {
    number:10
  }
  componentWillReceiveProps() {
    console.log('1. 子componentWillReceiveProps属性将要发生变化 ');
  }
  shouldComponentUpdate(nextProps, nextState) {
    console.log('2. 子componentShouldUpdate询问组件是否可以更新');
    // 调用此方法的时候会把新的属性对象和新的状态对象传递过来
    if (nextProps.number % 3 === 0) {
      return true;
    }
    return false;
  }
  componentWillUnmount() {
    console.log(' 3.子componentWillUnmount组件将要卸载 ');
  }
  render() {
    return (
      <div style={{border:'10px solid red'}}>
        {this.props.number}
      </div>
    );
  }
}
export default Counter;
复制代码

新版

React生命周期

创建时

constructor

初始化属性和状态

getDerivedStateFromProps

根据属性对象派生状态对象

  • 静态方法
  • 参数:新的属性对象,旧的状态对象
  • 用途:在没有这个生命周期函数之前,我们使用的数据来源可能是属性对象,也可能是状态对象,在我们的上文中的 放码过来 阶段就有所体现,我们可以通过这个生命周期函数将属性对象派生到状态对象上,使我们在代码中只通过 this.state.XXX 来绑定我们的数据。示例如下
import React, { Component } from 'react';
/**
 * 父
 */
class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      number:0
    }
  }
  render() {
    return (
      <div>
        <p>{this.state.number}</p>
        <button onClick={this.add}>+</button>
        <SubCounter number={this.state.number}/>
      </div>
    );
  }
  add = () => {
    this.setState({
      number:this.state.number+1
    })
  }
}
/**
 * 子
 */
class SubCounter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      number:0
    }
  }
  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.number % 2 === 0) {
      return {number:nextProps.number*2}
    } else {
      return {number:nextProps.number*3}
    }
  }
  render() {
    console.log(this.state);
    return (
      <div>
        <p>{this.state.number}</p>
      </div>
    );
  }
}
export default Counter;
复制代码

render

挂载(渲染)组件

componentDidMount

组件挂载(渲染)完成

更新时

getDerivedStateFromProps

根据属性对象派生状态对象

  • 静态方法
  • 参数:新的属性对象,旧的状态对象

shouldComponentUpdate

询问组件是否可以更新

  • 参数:新的状态对象
  • 返回: boolean
    true
    false
    

render

根据新的状态对象重新挂载(渲染)组件

getSnapshotbeforeUpdate

获取更新前的快照

  • 举例:在我们的日常开发中你一定会遇到这个问题,异步加载资源,当浏览器处于非第一屏的时候并且所在屏之前的模块并没有加载出来,你肯定不希望在所在屏之前的模块加载出来之后浏览器显示窗口仍然处于当前的高度,而是希望仍然处于我们所浏览屏的高度,在没有这个生命周期之前 react 处理这个问题是很棘手的。

未使用 getSnapshotbeforeUpdate

import React, { Component } from 'react';
class GetSnapshotBeforeUpdate extends Component {
  constructor(props) {
    super(props);
    this.wrapper = React.createRef();
    this.state = {
      messages:['4','3','2','1','0']
    }
  }
  componentDidMount() {
    setInterval(() => {
      this.setState(() => {
        this.state.messages.unshift(this.state.messages.length);
      }, () => {
          this.setState({
            messages: this.state.messages
          })
      })
    },1000)
  }
  render() {
    let style = {
      height: '100px',
      width: '200px',
      border: '1px solid red',
      overflow:'auto'
    }
    return (
      <ul style={style} ref={this.wrapper}>
        {
          this.state.messages.map((message, index) => <li key={index}>{message}</li>)
        }
      </ul>
    );
  }
}
export default GetSnapshotBeforeUpdate;
复制代码
React生命周期

使用 getSnapshotbeforeUpdate

import React, { Component } from 'react';
class GetSnapshotBeforeUpdate extends Component {
  ...
  getSnapshotBeforeUpdate() {
    // 返回更新内容的高度
    return this.wrapper.current.scrollHeight;
  }
  // 组件更新完毕
  componentDidUpdate(prevProps,prevState,prevScrollHeight) {
    console.log(prevProps,prevState,prevScrollHeight);
    this.wrapper.current.scrollTop = this.wrapper.current.scrollTop +
    (this.wrapper.current.scrollHeight - prevScrollHeight);
  }
  ...
export default GetSnapshotBeforeUpdate;
复制代码
React生命周期

componentDidUpdate

组件更新完成

卸载时

componentWillUnmount

组件卸载之前


以上所述就是小编给大家介绍的《React生命周期》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

硅谷百年史

硅谷百年史

[美]阿伦·拉奥(Arun Rao)、[美]皮埃罗·斯加鲁菲(Piero Scarruffi) / 闫景立、侯爱华 / 人民邮电出版社 / 2014-4-1 / 99.00

一百多年来,仅硅谷就培育了50多位诺贝尔奖获得者,以及无数依靠智慧和知识而成为百万富翁的人。这一人类历史上最伟大的科技创新与创业历程为什么会发生在硅谷?究竟是如何发生的?其他地方是否可以复制出“硅谷”? 《硅谷百年史——伟大的科技创新与创业历程(1900-2013)》以编年体的顺序,从无线电技术、晶体管、集成电路,到人类基因组、互联网和云计算,详尽地记述了硅谷在100多年中所发生的重大科技事......一起来看看 《硅谷百年史》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

随机密码生成器
随机密码生成器

多种字符组合密码

html转js在线工具
html转js在线工具

html转js在线工具