【React】class类组件

135 阅读6分钟

class类组件

类组件是基于 ES6 类(class)的 React****组件。在 React 16.8 Hooks 出现之前,类组件是实现状态和生命周期逻辑的主要方式,它们具备更复杂的功能。

特点

  • 使用 class 关键字定义,并继承自 React.Component

  • 能够使用 state 来管理组件的内部状态

  • 可以使用完整生命周期方法,如 componentDidMount

  • 通过 this.props 来访问传递给组件的属性(props

语法

import React, { Component } from "react";
// 组件接收的参数类型约束
type IProps = {};
// 组件内部state类型约束
type IState = {};
class HelloComponent extends Component<IProps, IState> {
  // 初始化
  constructor(props: IProps) {
    super(props);
  }
  // 返回组件布局
  render() {
    return <h1>Hello World!</h1>;
  }
}
// 导出组件
export default HelloComponent;

生命周期

import React, { Component } from "react";
type IProps = {};
type IState = {};
class HelloComponent extends Component<IProps, IState> {
  // 初始化
  constructor(props: IProps) {
    super(props);
  }
  // 组件挂载前- 常用组件生命周期函数 
  // react 16.3被废弃,建议使用constructor 或 componentDidMount
  componentWillMount() {
    console.log("componentWillMount");
  }
  // 组件挂载完成 - 常用组件生命周期函数
  componentDidMount() {
    console.log("componentDidMount");
  }
  // 组件接收到新的属性 - 常用组件生命周期函数 
  // react 16.3 被废弃建议使用getDerivedStateFromProps
  componentWillReceiveProps(nextProps: IProps) {
    console.log("componentWillReceiveProps");
  }
  getDerivedStateFromProps(nextProps: IProps, prevState: IState) {
    console.log("getDerivedStateFromProps");
    return null;
  }
  // 判断是否需要更新 - 场景使用
  shouldComponentUpdate(nextProps: IProps, nextState: IState) {
    console.log("shouldComponentUpdate");
    return true;
  }
  // 组件将要更新- 场景使用
  // react 16.3被废弃建议使用 getSnapshotBeforeUpdate
  componentWillUpdate(nextProps: IProps, nextState: IState) {
    console.log("componentWillUpdate");
  }
  getSnapshotBeforeUpdate(prevProps: IProps, prevState: IState) {
    console.log("getSnapshotBeforeUpdate");
  }
  // 组件更新完成- 场景使用
  componentDidUpdate(prevProps: IProps, prevState: IState) {
    console.log("componentDidUpdate");
  }
  // 组件将要卸载
  componentWillUnmount() {
    console.log("componentWillUnmount");
  }
  render() {
    return <h1>Hello World!</h1>;
  }
}
export default HelloComponent;

老版本生命周期方法:

  • constructor_:_组件初始化构造函数,只执行一次,可用来声明state
  • componentWillMount:组件挂载前调用
  • componentDidMount:组件挂载完成后调用
  • componentWillReceiveProps:组件接收到新的属性调用
  • shouldComponentUpdate:判断是否需要更新
  • componentWillUpdate:组件即将更新时调用
  • componentDidUpdate:组件更新完成调用
  • componentWillUnmount:组件将要卸载前调用

16.3之后版本生命周期方法:

  • constructor_:_组件初始化构造函数,只执行一次,可用来声明state
  • getDerivedStateFromProps:组件接收到新的属性调用
  • componentDidMount:组件挂载完成后调用
  • shouldComponentUpdate:判断是否需要更新
  • getSnapshotBeforeUpdate:在更新之前获取state快照
  • componentDidUpdate:组件更新完成调用
  • componentWillUnmount:组件将要卸载前调用

Constructor

class组件继承 React.Component 组件初始化时的构造函数,只执行一次,需要显示调用 super(props)****。

Constructor 中可以进行初始化操作比如声明 state 的属性

constructor(props: IProps) {
  super(props);
  this.state = {
    name"hello"
  }
}

getDerivedStateFromProps

说明:

1. getDerivedStateFromProps 存在的目的只有一个:让组件在props 变化时更新 state

2. 在组件挂载和更新时都会调用

组件接收到新的属性调用,返回一个对象,该对象会合并到state中。

/**
 * 返回一个对象,会合并到state中
 * @param nextProps 当父组件更新触发该函数
 * @param prevState 当自组件自身更新触发该函数
 * @returns 
 */
static getDerivedStateFromProps(nextProps: IProps, prevState: IState) {
  console.log("getDerivedStateFromProps", nextProps, prevState);
  return {};
}
import React, { Component } from "react";
type IProps = {
  name: string;
};
type IState = {};
class HelloComponent extends Component<IProps, IState> {
  // 初始化
  constructor(props: IProps) {
    super(props);
    this.state = {
      name"hello"
    }
  }
  // 组件挂载完成 - 常用组件生命周期函数
  componentDidMount() {
    // 自身更新状态
    setTimeout(() => {
      this.setState({
        name"hello world"
      })
    }, 2000);
  }
  /**
   * 返回一个对象,会合并到state中
   * @param nextProps 当父组件更新触发该函数
   * @param prevState 当自组件自身更新触发该函数
   * @returns 
   */
  static getDerivedStateFromProps(nextProps: IProps, prevState: IState) {
    console.log("getDerivedStateFromProps", nextProps, prevState);
    return {};
  }
  render() {
    return <h1>Hello World!</h1>;
  }
}
export default HelloComponent;
// 父组件更新属性
<HelloComponent name={count.toString()} />
<button onClick={() => setCount(count + 1)}>
  count is {count}
</button>
// 子组件更新时
//  getDerivedStateFromProps {name: '0'} {name: 'hello world'}
// 父组件更新时
// getDerivedStateFromProps {name: '1'} {name: 'hello world'} 

render

返回模版内容

 render() {
    return <h1>{this.state.name}</h1>;
  }

componentDidMount

组件挂载完成后调用,使用场景:网络请求、获取dom、设置事件监听等

componentDidMount() {
    // 自身更新状态
    setTimeout(() => {
      this.setState({
        name: "hello world"
      })
    }, 2000);
  }

shouldComponentUpdate

说明:只在更新阶段执行

返回一个布尔值,根据返回值判断是否需要更新。true则执行后续流程,false则不执行**render**函数及其后续生命周期函数。使用场景:性能优化。

/**
   * 判断是否需要更新 - 更新场景使用
   * @param nextProps 当父组件更新触发该函数
   * @param nextState 当自组件自身更新触发该函数
   * @returns true: 执行后续更新,false: 不执行更新
   */
  shouldComponentUpdate(nextProps: IProps, nextState: IState) {
    console.log("shouldComponentUpdate", nextProps, nextState);
    return true;
  }
import React, { Component } from "react";
type IProps = {
  name: string;
};
type IState = {};
class HelloComponent extends Component<IProps, IState> {
  // 初始化
  constructor(props: IProps) {
    super(props);
    this.state = {
      name"hello"
    }
  }
  // 组件挂载完成 - 常用组件生命周期函数
  componentDidMount() {
    console.log("componentDidMount");
    setTimeout(() => {
      this.setState({
        name"hello world"
      })
    }, 2000);
  }
  
  /**
   * 判断是否需要更新 - 场景使用
   * @param nextProps 当父组件更新触发该函数
   * @param nextState 当自组件自身更新触发该函数
   * @returns true: 执行后续更新,false: 不执行更新
   */
  shouldComponentUpdate(nextProps: IProps, nextState: IState) {
    console.log("shouldComponentUpdate", nextProps, nextState);
    return true;
  }
  render() {
    console.log("render");
    return <h1>Hello World!</h1>;
  }
}
export default HelloComponent;
// 父组件更新属性
<HelloComponent name={count.toString()} />
<button onClick={() => setCount(count + 1)}>
  count is {count}
</button>
// 子组件更新时
//  shouldComponentUpdate {name: '0'} {name: 'hello world'}
// 父组件更新时
// shouldComponentUpdate {name: '1'} {name: 'hello world'}

getSnapshotBeforeUpdate

说明:只在更新阶段执行

在更新之前获取state的快照,此时可以获取dom信息。

import React, { Component } from "react";
type IProps = {
  name: string;
};
type IState = {};
class HelloComponent extends Component<IProps, IState> {
  // 初始化
  constructor(props: IProps) {
    super(props);
    this.state = {
      name"hello"
    }
  }
  // 组件挂载完成 - 常用组件生命周期函数
  componentDidMount() {
    console.log("componentDidMount");
    setTimeout(() => {
      this.setState({
        name"hello world"
      })
    }, 2000);
  }
  /**
   * 判断是否需要更新 - 更新场景使用
   * @param prevProps 当父组件更新触发该函数
   * @param prevState 当自组件自身更新触发该函数
   * @returns 返回值将作为参数传递给 componentDidUpdate
   */
  getSnapshotBeforeUpdate(prevProps: IProps, prevState: IState) {
    console.log("getSnapshotBeforeUpdate", prevProps, prevState);
    return { value'getSnapshotBeforeUpdate' }
  }
  // 组件更新完成- 场景使用
  componentDidUpdate(prevProps: IProps, prevState: IState, valueFromSnapshotBeforeUpdate: any) {
    console.log("componentDidUpdate", prevProps, prevState, valueFromSnapshotBeforeUpdate);
  }
  render() {
    return <h1>Hello World!</h1>;
  }
}
export default HelloComponent;
// 父组件更新属性
<HelloComponent name={count.toString()} />
<button onClick={() => setCount(count + 1)}>
  count is {count}
</button>
// 子组件更新时, 获取到更新前的状态
//  sgetSnapshotBeforeUpdate {name: '0'} {name: 'hello'}
//  componentDidUpdate {name: 'hello'} {value: 'getSnapshotBeforeUpdate'}
// 父组件更新时, 获取到更新前的状态
// getSnapshotBeforeUpdate {name: '0'} {name: 'hello world'}
// componentDidUpdate {name: '0'} {name: 'hello world'} {value: 'getSnapshotBeforeUpdate'}

componentDidUpdate

组件更新完毕后调用

  /**
   * 组件更新完成- 更新场景使用
   * @param prevProps 当父组件更新触发该函数
   * @param prevState 当自组件自身更新触发该函数
   */
  componentDidUpdate(prevProps: IProps, prevState: IState, valueFromSnapshotBeforeUpdate: any) {
    console.log("componentDidUpdate", prevProps, prevState, valueFromSnapshotBeforeUpdate);
  }

componentWillUnmount

组件将要卸载前调用

// 组件将要卸载
  componentWillUnmount() {
    console.log("componentWillUnmount");
  }

生命周期流程图

image.png

组件挂载流程:constructor -> getDerivedStateFromProps -> render -> componentDidMount

组件更新流程:状态发生改变 -> getDerivedStateFromProps -> shouldComponentUpdate -> render -> getSnapshotBeforeUpdate -> componentDidUpdate

image.png

父子组件挂载流程:constructor -> getDerivedStateFromProps -> render -> child constructor -> child getDerivedStateFromProps -> child render -> child componentDidMount -> componentDidMount

父子组件更新流程:

  • 父组件更新:状态发生改变 -> getDerivedStateFromProps -> shouldComponentUpdate -> render
  • 子组件更新:child getDerivedStateFromProps -> child shouldComponentUpdate -> child render
  • 子组件:child getSnapshotBeforeUpdate
  • 父组件:getSnapshotBeforeUpdate
  • 子组件:child componentDidUpdate
  • 父组件:componentDidUpdate

参考

友情提示

见原文:【React】class类组件)

本文同步自微信公众号 "程序员小溪" ,这里只是同步,想看及时消息请移步我的公众号,不定时更新我的学习经验。