一、类组件与函数式组件概述
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
主要差异点如下:
2.2 状态管理与生命周期
状态管理和生命周期是两者差异最为明显的部分。
2.2.1 类组件的状态与生命周期
类组件通过 this.state 与 this.setState 管理状态,拥有完整的生命周期方法:
2.2.2 函数式组件的状态与生命周期
函数式组件通过 Hooks 管理状态与副作用:
#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 性能与渲染机制
从性能角度看,两者各有特点:
#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 也有自己的规则约束:
三、组件选型与最佳实践
理解差异之后,如何在实际项目中做出合理选型是关键。
3.1 何时使用类组件
虽然函数式组件已成为主流,但以下场景仍可能使用类组件:
3.2 何时使用函数式组件
新项目和重构场景应优先选择函数式组件:
3.3 迁移与改造建议
从类组件迁移到函数式组件时,建议遵循以下步骤:
#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 官方已明确推荐函数式组件作为未来发展方向,类组件虽不会被废弃,但新特性将优先在函数式组件上落地。开发者应:
回到最初的问题 "React的类组件和函数式组件有什么区别?",核心答案可以归纳为:类组件基于 class 与生命周期,强调实例化与继承;函数式组件基于函数与 Hooks,强调纯函数与组合。两者在能力上已趋于对等,但函数式组件凭借更简洁的语法、更优雅的逻辑复用和更现代的特性支持,已成为 React 开发的首选方案。