3.3 函数组件与类组件


3.3 函数组件与类组件

本节摘要:React 组件有函数组件与类组件两种写法,现代工程以函数组件为准。本节对照两者的结构、状态管理与生命周期风格,说明为什么推荐函数组件,并让你读得懂仍然存在的类组件代码。

本节阅读目标
阅读完本节,你应当能够:

  1. 各写一段函数组件与类组件并说清结构差异。
  2. 指出类组件里 this、state、生命周期方法的使用方式。
  3. 说清当下推荐函数组件的原因及 Hooks 的衔接位置。

一、一张皮囊的两种写法

同样是"显示一个列表并支持点击"的组件,用两种写法呈现一次。

函数组件:

function Todos({ items }) { const [checkedId, setCheckedId] = useState(null); return ( <ul> {items.map((it) => ( <li key={it.id} onClick={() => setCheckedId(it.id)}>{it.text}</li> ))} </ul> ); }

类组件:

class Todos extends React.Component { constructor(props) { super(props); this.state = { checkedId: null }; } handleClick = (id) => this.setState({ checkedId: id }); render() { return ( <ul> {this.props.items.map((it) => ( <li key={it.id} onClick={() => this.handleClick(it.id)}>{it.text}</li> ))} </ul> ); } }

肉眼可见的差异:类组件多了构造函数、this 前缀、render 方法;函数组件则直接返回 JSX,状态交给 Hook。

二、差异背后的原因

  • 状态来源:函数组件的状态来自 useState 等 Hook;类组件用 this.state 并在构造函数初始化。
  • this 语义:类组件里处处要 this,还要小心事件回调里 this 的指向(往往需要绑定上下文);函数组件没有 this 的烦恼。
  • 生命周期:类组件用 componentDidMount 等方法(对应 2.4 节),函数组件用 useEffect 表达同一件事。

三、为什么现在推荐函数组件

三点理由叠加,让函数组件成为默认选择。

  1. 写法更短、心智更贴近"组件是函数"的直觉,代码更易读。
  2. Hooks 把逻辑抽成可复用的能力,函数组件能直接复用,类组件做不到这种简洁复用。
  3. 现代工程与工具链对函数组件支持最好,新代码几乎都用它。

四、对照图:两种姿态怎么对待同一个数据集

图:函数组件与类组件的结构对照

图:函数组件与类组件的结构对照

五、比稿取舍

当团队评审"新组件用哪种写法"时,结论几乎一边倒:函数组件 + Hooks。类组件只在兜底或兼容历史依赖时出现。但也别一看到类组件就皱眉——能看懂、能维护它在新老交替期仍然必要。这正符合本教程一贯的态度:先弄懂两者,再明确选择。

五·一、同一份状态,两种写法的对照

把"一个输入框 + 一个实时显示"的最小例再对照一次,方便你直观比对两种写法。

用了函数组件加一个 state,代码是:

function Editor({ initialText = '' }) { const [text, setText] = useState(initialText); return <input value={text} onChange={(e) => setText(e.target.value)} />; }

换成类组件则是同一个需求的另一副面孔:

class Editor extends React.Component { state = { text: this.props.initialText || '' }; render() { return ( <input value={this.state.text} onChange={(e) => this.setState({ text: e.target.value })} /> ); } }

请对比两段里"改 text"的入口:函数组件是一个名为 setText 的普通函数,类组件是被包在 this.setState 里的方法。前者哪一步调用、更新后会发生什么都不需要你操心 this 指向;后者只要忘了绑定事件回调的 this,就会在运行时给你惊喜。这份"少一个心智负担"的差距,正是函数组件在团队评审里得分最高的那条理由。

五·二、把"个人项目、顺手就行"降到"团队共识"

写法这件事的一大分歧点是:单凭"函数组件更好"就能让所有人无缝写代码吗?答案是不能——还得把这条路定成团队共识。评审时最常见的来回是两类语气:一类是"我这就一个输入框,类组件写起来挺直白",另一类是"新功能一律函数组件,README 定死了"。前者是个人习惯驱动的,后者是规则驱动的。比稿现场需要的恰恰是后者:把"新组件用函数组件、旧代码可读可维护即可"写进文档,新入职的同学与久经沙场的老手才不至于每次开会都在写法上重新吵一轮。

这份共识还该顺手约定两件副产物:给"什么时候可以容忍类组件"画一条清晰的例外(比如某个第三方组件必须继承类基类),以及给"函数组件拆 Hooks 的粒度"打个底(一个 Hook 拆到多少人能一眼读懂)——让"循规"不变成"僵化"。把默认规则、允许例外、和边界都钉清楚,函数组件推荐才有落点,而不是一句空口号。

本节要点回顾

  • 两写法:函数式(现代默认)与类式(历史常见)。
  • 核心差异:state 来源、this 语义、生命周期表达三处不同。
  • 推荐理由:简短、无 this、Hooks 可复用。
  • 迁移态度:遇到旧类组件,先读懂再决定要不要用 hook 重写,别为时髦硬改。
  • 态度:新代码用函数组件,旧代码要能读懂维护。

类组件里出现过的生命周期方法,在函数组件里被 useEffect 等 Hook 重新表达——这正是下一节的主角。先讲数据流:State 与 Props。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U