欢迎光临
我们一直在努力

React的类组件和函数式组件有什么区别?:深入理解两种组件的核心差异与选型实践

一、类组件与函数式组件概述

React 作为当前最流行的前端框架之一,其组件化思想早已深入人心。在 React 的发展历程中,类组件和函数式组件是两种最为核心的组件形式。理解 "React的类组件和函数式组件有什么区别?" 这一问题,对于开发者编写高质量、可维护的 React 代码至关重要。

1.1 类组件的基本概念

类组件是 React 早期推荐的组件编写方式,它基于 ES6 的 class 语法创建,继承自 React.Component 或 React.PureComponent。类组件内部通过 this.state 管理状态,通过生命周期方法处理副作用,结构清晰但代码量相对较多。

import React, { Component } from 'react';
class ClassComponent extends Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentDidMount() {
console.log('组件已挂载');
}
render() {
return (
<div>
<p>当前计数: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
增加
</button>
</div>
);
}
}
export default ClassComponent;

1.2 函数式组件的基本概念

函数式组件是 React 16.8 版本之后推荐的主流写法,它本质上是一个返回 JSX 的 JavaScript 函数。借助 Hooks,函数式组件也能拥有状态和副作用处理能力,代码更加简洁、扁平。

import React, { useState, useEffect } from 'react';
function FunctionComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('组件已挂载');
}, []);
return (
<div>
<p>当前计数: {count}</p>
<button onClick={() => setCount(count + 1)}>增加</button>
</div>
);
}
export default FunctionComponent;

1.3 两种组件的演进历程

从 React 0.14 引入无状态函数式组件,到 React 16.8 推出 Hooks API,函数式组件的能力逐步增强。下图展示了两种组件的演进过程:

#publish-mermaid-1785810284302-0{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-1785810284302-0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-1785810284302-0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-1785810284302-0 .error-icon{fill:#552222;}#publish-mermaid-1785810284302-0 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-1785810284302-0 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-1785810284302-0 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-1785810284302-0 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-1785810284302-0 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-1785810284302-0 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-1785810284302-0 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-1785810284302-0 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-1785810284302-0 .marker.cross{stroke:#333333;}#publish-mermaid-1785810284302-0 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-1785810284302-0 p{margin:0;}#publish-mermaid-1785810284302-0 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#publish-mermaid-1785810284302-0 .cluster-label text{fill:#333;}#publish-mermaid-1785810284302-0 .cluster-label span{color:#333;}#publish-mermaid-1785810284302-0 .cluster-label span p{background-color:transparent;}#publish-mermaid-1785810284302-0 .label text,#publish-mermaid-1785810284302-0 span{fill:#333;color:#333;}#publish-mermaid-1785810284302-0 .node rect,#publish-mermaid-1785810284302-0 .node circle,#publish-mermaid-1785810284302-0 .node ellipse,#publish-mermaid-1785810284302-0 .node polygon,#publish-mermaid-1785810284302-0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1785810284302-0 .rough-node .label text,#publish-mermaid-1785810284302-0 .node .label text,#publish-mermaid-1785810284302-0 .image-shape .label,#publish-mermaid-1785810284302-0 .icon-shape .label{text-anchor:middle;}#publish-mermaid-1785810284302-0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#publish-mermaid-1785810284302-0 .rough-node .label,#publish-mermaid-1785810284302-0 .node .label,#publish-mermaid-1785810284302-0 .image-shape .label,#publish-mermaid-1785810284302-0 .icon-shape .label{text-align:center;}#publish-mermaid-1785810284302-0 .node.clickable{cursor:pointer;}#publish-mermaid-1785810284302-0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#publish-mermaid-1785810284302-0 .arrowheadPath{fill:#333333;}#publish-mermaid-1785810284302-0 .edgePath .path{stroke:#333333;stroke-width:1px;}#publish-mermaid-1785810284302-0 .flowchart-link{stroke:#333333;fill:none;}#publish-mermaid-1785810284302-0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1785810284302-0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284302-0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284302-0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#publish-mermaid-1785810284302-0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#publish-mermaid-1785810284302-0 .cluster text{fill:#333;}#publish-mermaid-1785810284302-0 .cluster span{color:#333;}#publish-mermaid-1785810284302-0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#publish-mermaid-1785810284302-0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#publish-mermaid-1785810284302-0 rect.text{fill:none;stroke-width:0;}#publish-mermaid-1785810284302-0 .icon-shape,#publish-mermaid-1785810284302-0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1785810284302-0 .icon-shape p,#publish-mermaid-1785810284302-0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#publish-mermaid-1785810284302-0 .icon-shape .label rect,#publish-mermaid-1785810284302-0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284302-0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#publish-mermaid-1785810284302-0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#publish-mermaid-1785810284302-0 .node .neo-node{stroke:#9370DB;}#publish-mermaid-1785810284302-0 [data-look=\”neo\”].node rect,#publish-mermaid-1785810284302-0 [data-look=\”neo\”].cluster rect,#publish-mermaid-1785810284302-0 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284302-0 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-1785810284302-0 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1785810284302-0 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284302-0 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-1785810284302-0 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284302-0 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-1785810284302-0 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284302-0 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284302-0 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

React 0.14

引入无状态函数式组件

React 15.x

类组件主导开发

React 16.8

推出 Hooks API

函数式组件崛起

React 18

并发特性与函数式组件深度融合

二、React的类组件和函数式组件有什么区别?

这是本文的核心问题。下面从多个维度进行深入剖析,帮助开发者全面理解两者的差异。

2.1 语法结构与写法差异

类组件使用 class 关键字声明,必须继承 React.Component,并实现 render 方法。函数式组件则是普通的 JavaScript 函数,接收 props 作为参数,返回 JSX。

#publish-mermaid-1785810284352-1{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-1785810284352-1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-1785810284352-1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-1785810284352-1 .error-icon{fill:#552222;}#publish-mermaid-1785810284352-1 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-1785810284352-1 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-1785810284352-1 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-1785810284352-1 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-1785810284352-1 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-1785810284352-1 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-1785810284352-1 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-1785810284352-1 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-1785810284352-1 .marker.cross{stroke:#333333;}#publish-mermaid-1785810284352-1 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-1785810284352-1 p{margin:0;}#publish-mermaid-1785810284352-1 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#publish-mermaid-1785810284352-1 .cluster-label text{fill:#333;}#publish-mermaid-1785810284352-1 .cluster-label span{color:#333;}#publish-mermaid-1785810284352-1 .cluster-label span p{background-color:transparent;}#publish-mermaid-1785810284352-1 .label text,#publish-mermaid-1785810284352-1 span{fill:#333;color:#333;}#publish-mermaid-1785810284352-1 .node rect,#publish-mermaid-1785810284352-1 .node circle,#publish-mermaid-1785810284352-1 .node ellipse,#publish-mermaid-1785810284352-1 .node polygon,#publish-mermaid-1785810284352-1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1785810284352-1 .rough-node .label text,#publish-mermaid-1785810284352-1 .node .label text,#publish-mermaid-1785810284352-1 .image-shape .label,#publish-mermaid-1785810284352-1 .icon-shape .label{text-anchor:middle;}#publish-mermaid-1785810284352-1 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#publish-mermaid-1785810284352-1 .rough-node .label,#publish-mermaid-1785810284352-1 .node .label,#publish-mermaid-1785810284352-1 .image-shape .label,#publish-mermaid-1785810284352-1 .icon-shape .label{text-align:center;}#publish-mermaid-1785810284352-1 .node.clickable{cursor:pointer;}#publish-mermaid-1785810284352-1 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#publish-mermaid-1785810284352-1 .arrowheadPath{fill:#333333;}#publish-mermaid-1785810284352-1 .edgePath .path{stroke:#333333;stroke-width:1px;}#publish-mermaid-1785810284352-1 .flowchart-link{stroke:#333333;fill:none;}#publish-mermaid-1785810284352-1 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1785810284352-1 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284352-1 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284352-1 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#publish-mermaid-1785810284352-1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#publish-mermaid-1785810284352-1 .cluster text{fill:#333;}#publish-mermaid-1785810284352-1 .cluster span{color:#333;}#publish-mermaid-1785810284352-1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#publish-mermaid-1785810284352-1 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#publish-mermaid-1785810284352-1 rect.text{fill:none;stroke-width:0;}#publish-mermaid-1785810284352-1 .icon-shape,#publish-mermaid-1785810284352-1 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1785810284352-1 .icon-shape p,#publish-mermaid-1785810284352-1 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#publish-mermaid-1785810284352-1 .icon-shape .label rect,#publish-mermaid-1785810284352-1 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284352-1 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#publish-mermaid-1785810284352-1 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#publish-mermaid-1785810284352-1 .node .neo-node{stroke:#9370DB;}#publish-mermaid-1785810284352-1 [data-look=\”neo\”].node rect,#publish-mermaid-1785810284352-1 [data-look=\”neo\”].cluster rect,#publish-mermaid-1785810284352-1 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284352-1 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-1785810284352-1 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1785810284352-1 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284352-1 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-1785810284352-1 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284352-1 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-1785810284352-1 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284352-1 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284352-1 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

组件写法对比

类组件

函数式组件

继承 React.Component

必须实现 render 方法

使用 this 访问 props 与 state

普通 JavaScript 函数

接收 props 参数

直接返回 JSX

主要差异点如下:

  • 类组件需要 import Component 并 extends 继承;函数式组件只需一个普通函数。
  • 类组件强制要求 render 方法返回 JSX;函数式组件直接 return。
  • 类组件通过 this.props 访问属性;函数式组件通过函数参数获取。
  • 类组件内部使用 this 绑定方法;函数式组件无需考虑 this 指向。
  • 2.2 状态管理与生命周期

    状态管理和生命周期是两者差异最为明显的部分。

    2.2.1 类组件的状态与生命周期

    类组件通过 this.state 与 this.setState 管理状态,拥有完整的生命周期方法:

  • 挂载阶段:constructor、getDerivedStateFromProps、render、componentDidMount。
  • 更新阶段:getDerivedStateFromProps、shouldComponentUpdate、render、getSnapshotBeforeUpdate、componentDidUpdate。
  • 卸载阶段:componentWillUnmount。
  • 2.2.2 函数式组件的状态与生命周期

    函数式组件通过 Hooks 管理状态与副作用:

  • useState:管理本地状态。
  • useEffect:处理副作用,可模拟 componentDidMount、componentDidUpdate、componentWillUnmount。
  • useLayoutEffect:同步执行副作用。
  • useMemo 与 useCallback:进行性能优化。
  • #publish-mermaid-1785810284392-2{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-1785810284392-2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-1785810284392-2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-1785810284392-2 .error-icon{fill:#552222;}#publish-mermaid-1785810284392-2 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-1785810284392-2 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-1785810284392-2 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-1785810284392-2 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-1785810284392-2 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-1785810284392-2 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-1785810284392-2 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-1785810284392-2 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-1785810284392-2 .marker.cross{stroke:#333333;}#publish-mermaid-1785810284392-2 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-1785810284392-2 p{margin:0;}#publish-mermaid-1785810284392-2 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#publish-mermaid-1785810284392-2 .cluster-label text{fill:#333;}#publish-mermaid-1785810284392-2 .cluster-label span{color:#333;}#publish-mermaid-1785810284392-2 .cluster-label span p{background-color:transparent;}#publish-mermaid-1785810284392-2 .label text,#publish-mermaid-1785810284392-2 span{fill:#333;color:#333;}#publish-mermaid-1785810284392-2 .node rect,#publish-mermaid-1785810284392-2 .node circle,#publish-mermaid-1785810284392-2 .node ellipse,#publish-mermaid-1785810284392-2 .node polygon,#publish-mermaid-1785810284392-2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1785810284392-2 .rough-node .label text,#publish-mermaid-1785810284392-2 .node .label text,#publish-mermaid-1785810284392-2 .image-shape .label,#publish-mermaid-1785810284392-2 .icon-shape .label{text-anchor:middle;}#publish-mermaid-1785810284392-2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#publish-mermaid-1785810284392-2 .rough-node .label,#publish-mermaid-1785810284392-2 .node .label,#publish-mermaid-1785810284392-2 .image-shape .label,#publish-mermaid-1785810284392-2 .icon-shape .label{text-align:center;}#publish-mermaid-1785810284392-2 .node.clickable{cursor:pointer;}#publish-mermaid-1785810284392-2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#publish-mermaid-1785810284392-2 .arrowheadPath{fill:#333333;}#publish-mermaid-1785810284392-2 .edgePath .path{stroke:#333333;stroke-width:1px;}#publish-mermaid-1785810284392-2 .flowchart-link{stroke:#333333;fill:none;}#publish-mermaid-1785810284392-2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1785810284392-2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284392-2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284392-2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#publish-mermaid-1785810284392-2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#publish-mermaid-1785810284392-2 .cluster text{fill:#333;}#publish-mermaid-1785810284392-2 .cluster span{color:#333;}#publish-mermaid-1785810284392-2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#publish-mermaid-1785810284392-2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#publish-mermaid-1785810284392-2 rect.text{fill:none;stroke-width:0;}#publish-mermaid-1785810284392-2 .icon-shape,#publish-mermaid-1785810284392-2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1785810284392-2 .icon-shape p,#publish-mermaid-1785810284392-2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#publish-mermaid-1785810284392-2 .icon-shape .label rect,#publish-mermaid-1785810284392-2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284392-2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#publish-mermaid-1785810284392-2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#publish-mermaid-1785810284392-2 .node .neo-node{stroke:#9370DB;}#publish-mermaid-1785810284392-2 [data-look=\”neo\”].node rect,#publish-mermaid-1785810284392-2 [data-look=\”neo\”].cluster rect,#publish-mermaid-1785810284392-2 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284392-2 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-1785810284392-2 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1785810284392-2 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284392-2 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-1785810284392-2 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284392-2 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-1785810284392-2 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284392-2 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284392-2 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}对应对应对应

    生命周期对照

    类组件

    函数式组件

    componentDidMount

    componentDidUpdate

    componentWillUnmount

    useEffect 空依赖

    useEffect 带依赖

    useEffect return 清理函数

    2.3 this 指向与事件处理

    类组件中的 this 指向是初学者常遇到的痛点。在类组件中,事件处理函数默认不会绑定 this,需要手动 bind 或使用箭头函数:

    class BindDemo extends Component {
    constructor(props) {
    super(props);
    this.state = { value: '' };
    this.handleChange = this.handleChange.bind(this);
    }
    handleChange(e) {
    this.setState({ value: e.target.value });
    }
    render() {
    return <input onChange={this.handleChange} />;
    }
    }

    函数式组件则完全不存在 this 绑定问题,函数作用域天然清晰:

    function FunctionDemo() {
    const [value, setValue] = useState('');
    const handleChange = (e) => {
    setValue(e.target.value);
    };
    return <input onChange={handleChange} />;
    }

    2.4 性能与渲染机制

    从性能角度看,两者各有特点:

  • 类组件通过 shouldComponentUpdate 或继承 PureComponent 控制重渲染。
  • 函数式组件通过 React.memo 进行记忆化,避免不必要的重渲染。
  • 函数式组件在 Hooks 调用时会有一定的闭包开销,但现代 React 已大幅优化。
  • 类组件实例化时会创建较多属性与方法,内存占用略高。
  • #publish-mermaid-1785810284507-3{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-1785810284507-3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-1785810284507-3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-1785810284507-3 .error-icon{fill:#552222;}#publish-mermaid-1785810284507-3 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-1785810284507-3 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-1785810284507-3 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-1785810284507-3 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-1785810284507-3 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-1785810284507-3 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-1785810284507-3 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-1785810284507-3 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-1785810284507-3 .marker.cross{stroke:#333333;}#publish-mermaid-1785810284507-3 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-1785810284507-3 p{margin:0;}#publish-mermaid-1785810284507-3 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#publish-mermaid-1785810284507-3 .cluster-label text{fill:#333;}#publish-mermaid-1785810284507-3 .cluster-label span{color:#333;}#publish-mermaid-1785810284507-3 .cluster-label span p{background-color:transparent;}#publish-mermaid-1785810284507-3 .label text,#publish-mermaid-1785810284507-3 span{fill:#333;color:#333;}#publish-mermaid-1785810284507-3 .node rect,#publish-mermaid-1785810284507-3 .node circle,#publish-mermaid-1785810284507-3 .node ellipse,#publish-mermaid-1785810284507-3 .node polygon,#publish-mermaid-1785810284507-3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1785810284507-3 .rough-node .label text,#publish-mermaid-1785810284507-3 .node .label text,#publish-mermaid-1785810284507-3 .image-shape .label,#publish-mermaid-1785810284507-3 .icon-shape .label{text-anchor:middle;}#publish-mermaid-1785810284507-3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#publish-mermaid-1785810284507-3 .rough-node .label,#publish-mermaid-1785810284507-3 .node .label,#publish-mermaid-1785810284507-3 .image-shape .label,#publish-mermaid-1785810284507-3 .icon-shape .label{text-align:center;}#publish-mermaid-1785810284507-3 .node.clickable{cursor:pointer;}#publish-mermaid-1785810284507-3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#publish-mermaid-1785810284507-3 .arrowheadPath{fill:#333333;}#publish-mermaid-1785810284507-3 .edgePath .path{stroke:#333333;stroke-width:1px;}#publish-mermaid-1785810284507-3 .flowchart-link{stroke:#333333;fill:none;}#publish-mermaid-1785810284507-3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1785810284507-3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284507-3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284507-3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#publish-mermaid-1785810284507-3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#publish-mermaid-1785810284507-3 .cluster text{fill:#333;}#publish-mermaid-1785810284507-3 .cluster span{color:#333;}#publish-mermaid-1785810284507-3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#publish-mermaid-1785810284507-3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#publish-mermaid-1785810284507-3 rect.text{fill:none;stroke-width:0;}#publish-mermaid-1785810284507-3 .icon-shape,#publish-mermaid-1785810284507-3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1785810284507-3 .icon-shape p,#publish-mermaid-1785810284507-3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#publish-mermaid-1785810284507-3 .icon-shape .label rect,#publish-mermaid-1785810284507-3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284507-3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#publish-mermaid-1785810284507-3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#publish-mermaid-1785810284507-3 .node .neo-node{stroke:#9370DB;}#publish-mermaid-1785810284507-3 [data-look=\”neo\”].node rect,#publish-mermaid-1785810284507-3 [data-look=\”neo\”].cluster rect,#publish-mermaid-1785810284507-3 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284507-3 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-1785810284507-3 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1785810284507-3 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284507-3 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-1785810284507-3 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284507-3 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-1785810284507-3 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284507-3 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284507-3 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    性能优化对比

    类组件

    函数式组件

    shouldComponentUpdate

    PureComponent 浅比较

    手动控制渲染

    React.memo

    useMemo 缓存值

    useCallback 缓存函数

    2.5 Hooks 的引入与影响

    Hooks 是 React 16.8 引入的特性,它让函数式组件具备了状态管理、副作用处理、上下文消费等能力。Hooks 的核心价值在于:

  • 逻辑复用更优雅,自定义 Hooks 替代高阶组件与 render props。
  • 关注点分离,相关逻辑聚合在同一 Hook 中。
  • 代码量更少,结构更扁平。
  • 无 this 绑定问题,减少心智负担。
  • 但 Hooks 也有自己的规则约束:

  • 只能在函数最外层调用,不能在循环、条件或嵌套函数中调用。
  • 只能在函数式组件或自定义 Hooks 中调用。
  • 三、组件选型与最佳实践

    理解差异之后,如何在实际项目中做出合理选型是关键。

    3.1 何时使用类组件

    虽然函数式组件已成为主流,但以下场景仍可能使用类组件:

  • 维护历史遗留项目,技术栈尚未升级到 React 16.8 以上。
  • 某些第三方库依赖类的实例方法或继承机制。
  • 需要使用错误边界,类组件的 componentDidCatch 仍是官方推荐方式。
  • 团队对类组件更加熟悉,且没有强烈迁移意愿。
  • 3.2 何时使用函数式组件

    新项目和重构场景应优先选择函数式组件:

  • 新项目直接采用函数式组件 + Hooks。
  • 需要复用状态逻辑,自定义 Hooks 比高阶组件更直观。
  • 追求代码简洁与可读性。
  • 需要利用 React 18 并发特性与 Suspense。
  • 3.3 迁移与改造建议

    从类组件迁移到函数式组件时,建议遵循以下步骤:

  • 第一步:评估迁移价值,优先迁移业务逻辑复杂的组件。
  • 第二步:将 constructor 中的状态初始化改为 useState。
  • 第三步:将生命周期方法映射为 useEffect、useLayoutEffect。
  • 第四步:将类方法改为函数声明,移除 this 绑定。
  • 第五步:使用 React.memo 包裹组件,进行性能验证。
  • 第六步:编写单元测试,确保行为一致。
  • #publish-mermaid-1785810284559-4{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-1785810284559-4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-1785810284559-4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-1785810284559-4 .error-icon{fill:#552222;}#publish-mermaid-1785810284559-4 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-1785810284559-4 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-1785810284559-4 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-1785810284559-4 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-1785810284559-4 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-1785810284559-4 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-1785810284559-4 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-1785810284559-4 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-1785810284559-4 .marker.cross{stroke:#333333;}#publish-mermaid-1785810284559-4 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-1785810284559-4 p{margin:0;}#publish-mermaid-1785810284559-4 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#publish-mermaid-1785810284559-4 .cluster-label text{fill:#333;}#publish-mermaid-1785810284559-4 .cluster-label span{color:#333;}#publish-mermaid-1785810284559-4 .cluster-label span p{background-color:transparent;}#publish-mermaid-1785810284559-4 .label text,#publish-mermaid-1785810284559-4 span{fill:#333;color:#333;}#publish-mermaid-1785810284559-4 .node rect,#publish-mermaid-1785810284559-4 .node circle,#publish-mermaid-1785810284559-4 .node ellipse,#publish-mermaid-1785810284559-4 .node polygon,#publish-mermaid-1785810284559-4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1785810284559-4 .rough-node .label text,#publish-mermaid-1785810284559-4 .node .label text,#publish-mermaid-1785810284559-4 .image-shape .label,#publish-mermaid-1785810284559-4 .icon-shape .label{text-anchor:middle;}#publish-mermaid-1785810284559-4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#publish-mermaid-1785810284559-4 .rough-node .label,#publish-mermaid-1785810284559-4 .node .label,#publish-mermaid-1785810284559-4 .image-shape .label,#publish-mermaid-1785810284559-4 .icon-shape .label{text-align:center;}#publish-mermaid-1785810284559-4 .node.clickable{cursor:pointer;}#publish-mermaid-1785810284559-4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#publish-mermaid-1785810284559-4 .arrowheadPath{fill:#333333;}#publish-mermaid-1785810284559-4 .edgePath .path{stroke:#333333;stroke-width:1px;}#publish-mermaid-1785810284559-4 .flowchart-link{stroke:#333333;fill:none;}#publish-mermaid-1785810284559-4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1785810284559-4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284559-4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284559-4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#publish-mermaid-1785810284559-4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#publish-mermaid-1785810284559-4 .cluster text{fill:#333;}#publish-mermaid-1785810284559-4 .cluster span{color:#333;}#publish-mermaid-1785810284559-4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#publish-mermaid-1785810284559-4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#publish-mermaid-1785810284559-4 rect.text{fill:none;stroke-width:0;}#publish-mermaid-1785810284559-4 .icon-shape,#publish-mermaid-1785810284559-4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1785810284559-4 .icon-shape p,#publish-mermaid-1785810284559-4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#publish-mermaid-1785810284559-4 .icon-shape .label rect,#publish-mermaid-1785810284559-4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1785810284559-4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#publish-mermaid-1785810284559-4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#publish-mermaid-1785810284559-4 .node .neo-node{stroke:#9370DB;}#publish-mermaid-1785810284559-4 [data-look=\”neo\”].node rect,#publish-mermaid-1785810284559-4 [data-look=\”neo\”].cluster rect,#publish-mermaid-1785810284559-4 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284559-4 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-1785810284559-4 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1785810284559-4 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284559-4 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-1785810284559-4 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284559-4 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-1785810284559-4 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284559-4 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1785810284559-4 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    类组件迁移函数式组件

    评估迁移价值

    state 改为 useState

    生命周期改为 useEffect

    移除 this 绑定

    React.memo 优化

    单元测试验证

    迁移完成

    四、总结与展望

    4.1 核心差异回顾

    下表总结了类组件与函数式组件的核心差异:

    | 对比维度 | 类组件 | 函数式组件 |

    |———|——–|———–|

    | 语法 | class 继承 Component | 普通函数 |

    | 状态管理 | this.state 与 setState | useState |

    | 生命周期 | 完整生命周期方法 | useEffect 等 Hooks |

    | this 绑定 | 需要手动绑定 | 无 this 问题 |

    | 逻辑复用 | 高阶组件、render props | 自定义 Hooks |

    | 性能优化 | shouldComponentUpdate、PureComponent | React.memo、useMemo |

    | 代码量 | 较多 | 较少 |

    | 心智负担 | 较大 | 较小 |

    4.2 未来发展趋势

    React 官方已明确推荐函数式组件作为未来发展方向,类组件虽不会被废弃,但新特性将优先在函数式组件上落地。开发者应:

  • 掌握 Hooks 的核心原理与最佳实践。
  • 理解类组件的运行机制,便于维护历史代码。
  • 关注 React 18 及后续版本的并发模式与 Server Components。
  • 在团队中推动函数式组件的采用与最佳实践沉淀。
  • 回到最初的问题 "React的类组件和函数式组件有什么区别?",核心答案可以归纳为:类组件基于 class 与生命周期,强调实例化与继承;函数式组件基于函数与 Hooks,强调纯函数与组合。两者在能力上已趋于对等,但函数式组件凭借更简洁的语法、更优雅的逻辑复用和更现代的特性支持,已成为 React 开发的首选方案。

    赞(0)
    未经允许不得转载:171主机测评 » React的类组件和函数式组件有什么区别?:深入理解两种组件的核心差异与选型实践
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址