React生命周期

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

内容简介:如果将组件比作我们图中的: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生命周期》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Web API的设计与开发

Web API的设计与开发

[日] 水野贵明 / 盛荣 / 人民邮电出版社 / 2017-6 / 52.00元

本书结合丰富的实例,详细讲解了Web API的设计、开发与运维相关的知识。第1章介绍Web API的概要;第2章详述端点的设计与请求的形式;第3章介绍响应数据的设计;第4章介绍如何充分利用HTTP协议规范;第5章介绍如何开发方便更改设计的Web API;第6章介绍如何开发牢固的Web API。 本书不仅适合在工作中需要设计、开发或修改Web API的技术人员阅读,对想了解技术细节的产品经理、运维人......一起来看看 《Web API的设计与开发》 这本书的介绍吧!

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具