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");
}
生命周期流程图
组件挂载流程:constructor -> getDerivedStateFromProps -> render -> componentDidMount
组件更新流程:状态发生改变 -> getDerivedStateFromProps -> shouldComponentUpdate -> render -> getSnapshotBeforeUpdate -> componentDidUpdate
父子组件挂载流程: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类组件)
本文同步自微信公众号 "程序员小溪" ,这里只是同步,想看及时消息请移步我的公众号,不定时更新我的学习经验。