React 类组件与函数式组件

你想了解的类组件(Class Component)和函数式组件(Functional Component)是 React 中两种核心的组件编写方式,前者是 React 早期的主流方案,后者则在 Hooks 推出后成为官方推荐的首选。本文会从语法结构、状态管理、生命周期、性能、使用场景等维度,帮你理清二者的核心区别,以及不同场景下的选型思路。

一、核心定义与语法差异

1. 类组件(Class Component)

类组件是基于 ES6 类语法创建的组件,必须继承React.ComponentReact.PureComponent,并通过render()方法返回 JSX。

jsx

import React from 'react'; // 类组件示例 class ClassCounter extends React.Component { // 构造函数:初始化状态、绑定方法 constructor(props) { super(props); // 初始化state this.state = { count: 0 }; // 手动绑定this(避免回调中this丢失) this.handleIncrement = this.handleIncrement.bind(this); } // 自定义方法 handleIncrement() { // 修改状态(必须用setState) this.setState({ count: this.state.count + 1 }); } // 必须实现render方法 render() { return ( <div> <p>计数:{this.state.count}</p> <button onClick={this.handleIncrement}>+1</button> </div> ); } }

2. 函数式组件(Functional Component)

函数式组件本质是一个普通的 JavaScript 函数,接收props作为参数,直接返回 JSX。Hooks(React 16.8+)推出后,函数式组件才具备了状态管理和生命周期能力。

jsx

import React, { useState } from 'react'; // 函数式组件示例 function FunctionalCounter(props) { // 用useState Hook管理状态 const [count, setCount] = useState(0); // 自定义方法(无需绑定this) const handleIncrement = () => { // 直接修改状态 setCount(count + 1); }; // 直接返回JSX,无需render方法 return ( <div> <p>计数:{count}</p> <button onClick={handleIncrement}>+1</button> </div> ); }

二、核心区别对比

为了让你更清晰地对比,我整理了关键维度的差异表:

对比维度类组件(Class Component)函数式组件(Functional Component)
语法结构基于 ES6 Class,需继承 React.Component普通 JS 函数,语法更简洁,无冗余代码
状态管理this.statesetState()管理状态useState/useReducerHooks 管理状态
this 指向存在 this,需手动绑定(或用箭头函数)无 this,避免 this 指向混乱问题
生命周期有明确的生命周期方法(componentDidMount 等)useEffectHook 模拟所有生命周期逻辑
性能优化可继承PureComponent或实现shouldComponentUpdateReact.memo(浅比较 props)+useMemo/useCallback优化
代码复用依赖高阶组件(HOC)、Render Props依赖 Hooks(更简洁,无嵌套地狱)
错误边界仅类组件可作为错误边界(实现 componentDidCatch)无法直接作为错误边界(需包裹类组件)
官方推荐仅兼容老项目,不推荐新开发React 16.8 + 官方首选方案

三、关键能力深度解析

1. 状态管理差异

类组件
  • 状态是对象形式this.state = { count: 0, name: 'test' }
  • 修改状态必须用setState(),且setState异步更新(合成事件中),可能需要依赖前一个状态:

    jsx

    // 正确:依赖前状态更新 this.setState(prevState => ({ count: prevState.count + 1 }));
  • 无法在函数中直接捕获最新状态(需用 ref 或 setState 回调)。
函数式组件
  • 状态可以是任意类型(数字、字符串、对象、数组等),useState按需求拆分:

    jsx

    const [count, setCount] = useState(0); const [user, setUser] = useState({ name: '张三' });
  • setState直接替换(而非合并),更新对象 / 数组时需手动合并:

    jsx

    // 更新对象:合并原有属性 setUser(prev => ({ ...prev, age: 25 }));
  • 能通过闭包直接捕获最新状态(但需注意依赖项问题)。

2. 生命周期模拟(函数式组件 vs 类组件)

类组件的生命周期方法在函数式组件中都能通过useEffect模拟,对应关系如下:

类组件生命周期函数式组件实现方式
componentDidMountuseEffect (() => { /* 逻辑 */ }, [])
componentDidUpdateuseEffect (() => { /* 逻辑 */ }, [依赖项])
componentWillUnmountuseEffect (() => { return () => { /* 清理 */ } }, [])
componentDidMount + componentDidUpdateuseEffect (() => { /* 逻辑 */ })

示例:模拟类组件的生命周期

jsx

// 函数式组件模拟生命周期 function LifecycleDemo() { const [count, setCount] = useState(0); // componentDidMount:仅挂载时执行 useEffect(() => { console.log('组件挂载'); // componentWillUnmount:清理函数 return () => { console.log('组件卸载'); }; }, []); // componentDidUpdate:count变化时执行 useEffect(() => { console.log('count更新为:', count); }, [count]); return ( <div> <p>{count}</p> <button onClick={() => setCount(count + 1)}>+1</button> </div> ); }

3. 性能优化差异

类组件优化
  • 继承React.PureComponent:自动对propsstate浅比较,避免不必要的重渲染;
  • 手动实现shouldComponentUpdate:自定义比较逻辑,返回false阻止重渲染。
函数式组件优化
  • React.memo:高阶组件,对props做浅比较,类似PureComponent
  • useMemo:缓存计算结果,避免每次渲染重复计算;
  • useCallback:缓存函数引用,避免因函数重新创建导致子组件重渲染。

示例:函数式组件性能优化

jsx

// React.memo:浅比较props const MemoizedChild = React.memo(({ onIncrement }) => { console.log('子组件渲染'); return <button onClick={onIncrement}>+1</button>; }); function Parent() { const [count, setCount] = useState(0); // useCallback:缓存函数引用 const handleIncrement = useCallback(() => { setCount(count + 1); }, [count]); // useMemo:缓存计算结果 const doubleCount = useMemo(() => { return count * 2; }, [count]); return ( <div> <p>计数:{count},双倍:{doubleCount}</p> <MemoizedChild onIncrement={handleIncrement} /> </div> ); }

四、使用场景与选型建议

1. 优先使用函数式组件的场景

  • 新项目开发:React 官方推荐,代码更简洁、易维护;
  • 需要复用逻辑:Hooks(如useStateuseEffect、自定义 Hook)比 HOC/Render Props 更优雅;
  • 团队协作:降低学习成本(无需理解 this、生命周期),减少 bug;
  • 性能敏感场景:通过React.memo+useCallback/useMemo可精准优化。

2. 仍需使用类组件的场景

  • 维护老项目:老代码基于类组件,无需强行重构;
  • 实现错误边界:函数式组件无法直接实现componentDidCatch,需用类组件:

    jsx

    class ErrorBoundary extends React.Component { state = { hasError: false }; static getDerivedStateFromError() { return { hasError: true }; } componentDidCatch(error, info) { console.log('捕获错误:', error, info); } render() { if (this.state.hasError) { return <div>出错了!</div>; } return this.props.children; } } // 使用:包裹函数式组件 <ErrorBoundary> <FunctionalComponent /> </ErrorBoundary>
  • 极少数复杂场景:如需要深度定制shouldComponentUpdate且 Hooks 优化成本更高。

五、迁移指南(类组件 → 函数式组件)

如果需要将类组件迁移为函数式组件,可遵循以下步骤:

  1. 替换类定义为函数:移除classextends React.Component,改为函数接收props
  2. 替换 state:将this.state拆分为多个useState
  3. 替换生命周期:用useEffect模拟componentDidMount/DidUpdate/WillUnmount
  4. 移除 this 绑定:函数内方法无需绑定 this,直接定义箭头函数或普通函数;
  5. 替换 this.props:直接使用函数参数props
  6. 性能优化:用React.memo替代PureComponentuseCallback/useMemo替代手动优化。

迁移示例

jsx

// 类组件 class OldComponent extends React.Component { state = { text: '' }; componentDidMount() { console.log('挂载'); } handleChange = (e) => { this.setState({ text: e.target.value }); }; render() { return <input value={this.state.text} onChange={this.handleChange} />; } } // 迁移后的函数式组件 function NewComponent(props) { const [text, setText] = useState(''); useEffect(() => { console.log('挂载'); }, []); const handleChange = (e) => { setText(e.target.value); }; return <input value={text} onChange={handleChange} />; } // 性能优化:添加React.memo const MemoizedNewComponent = React.memo(NewComponent);

总结

  1. 核心差异:类组件基于 ES6 Class,依赖this和生命周期方法;函数式组件是纯函数,依赖 Hooks 实现状态和生命周期,语法更简洁、无 this 陷阱。
  2. 选型原则:新项目优先用函数式组件 + Hooks,老项目 / 错误边界场景保留类组件。
  3. 优化方式:类组件用PureComponent/shouldComponentUpdate,函数式组件用React.memo+useCallback/useMemo

掌握二者的区别和选型思路,能让你在 React 开发中更灵活地选择合适的组件形式,写出更高效、易维护的代码。

👉 **觉得有用的点点关注谢谢~**

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1196762.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【毕业设计】基于springboot的医药管理系统(源码+文档+远程调试,全bao定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

用java实现简易计算器_java窗口简易计算器,零基础入门到精通,收藏这篇就够了

一.源代码 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public class SimpleCalculator extends JFrame {private JTextField display;private double firstNumber 0;private String operator &quo…

学校用维普检测,这6款降AI工具更稳

维普AIGC检测高&#xff1f;6款工具帮你降到合格线 TL;DR&#xff1a;维普AIGC检测算法和知网不同&#xff0c;很多知网能过的工具在维普可能过不了。实测对维普效果最好的是嘎嘎降AI&#xff08;67%→9%&#xff09;&#xff0c;其次是比话降AI&#xff08;60%→12%&#xff0…

基于 YOLOv8 的焊缝表面缺陷智能检测系统实战(附完整训练与可视化界面)

基于 YOLOv8 的焊缝表面缺陷智能检测系统实战&#xff08;附完整训练与可视化界面&#xff09; 前言&#xff1a;为什么焊缝检测必须走向智能化&#xff1f; 在工业制造领域&#xff0c;焊接质量几乎决定了产品结构强度与安全等级。传统的焊缝检测方式主要依赖人工肉眼检查或…

新能源储能设备人机交互利器:高可靠串口屏的全链路适配方案解析

储能设备系统作为新能源产业链的核心环节,涵盖大型储能电站、家用储能柜、便携式储能设备等多元形态,其串口屏需精准呈现充放电功率、SOC电量、电池单体电压、故障状态等关键数据,同时适配户外高低温、强电磁干扰、…

Vue 中 v-for 与 v-if 优先级

在 Vue 开发中&#xff0c;v-for&#xff08;列表渲染&#xff09;和v-if&#xff08;条件渲染&#xff09;是最常用的两个指令&#xff0c;但当它们出现在同一个元素上时&#xff0c;很多开发者会踩坑 —— 核心问题就是优先级导致的逻辑异常和性能损耗。本文将从优先级原理、…

6款降AI工具维普实测,差距比你想的大

维普AIGC检测高&#xff1f;6款工具帮你降到合格线 TL;DR&#xff1a;维普AIGC检测算法和知网不同&#xff0c;很多知网能过的工具在维普可能过不了。实测对维普效果最好的是嘎嘎降AI&#xff08;67%→9%&#xff09;&#xff0c;其次是比话降AI&#xff08;60%→12%&#xff0…

1-21午夜盘思

1、大盘无忧; 2、情绪方面:新华百货维持高位震荡,高位宽容,情绪周期弱转强,小票已经开始宽容;三市成交2.6万亿,成交持续萎缩,缩量确实有点厉害,最大的影响是存量资金只能驱动一个主流题材,其他很可能是渣;所…

基于 YOLOv8 的牛行为智能识别系统实战(从模型训练到可视化部署)

基于 YOLOv8 的牛行为智能识别系统实战&#xff08;从模型训练到可视化部署&#xff09; 一、背景&#xff1a;为什么要做牛行为识别&#xff1f; 在现代化畜牧业中&#xff0c;“看牛”本质上已经成为一个数据问题。 牛的站立、行走、卧倒等行为&#xff0c;直接反映了健康状…

知网能过≠维普能过,这点很多人不知道

维普AIGC检测高&#xff1f;6款工具帮你降到合格线 TL;DR&#xff1a;维普AIGC检测算法和知网不同&#xff0c;很多知网能过的工具在维普可能过不了。实测对维普效果最好的是嘎嘎降AI&#xff08;67%→9%&#xff09;&#xff0c;其次是比话降AI&#xff08;60%→12%&#xff0…

直面Oracle国产化替代的典型陷阱与攻坚策略

Oracle数据库迁移实战 KingbaseES 集成了丰富的 Oracle 兼容特性&#xff0c;这在实际迁移场景中通常只需对原导出脚本进行少量调整&#xff0c;甚至在全功能兼容时无需修改。此外&#xff0c;系统还支持使用 KDTS、KFS 等多种辅助工具&#xff0c;进一步简化迁移流程。 本节…

异构环境下分布式深度学习数据并行技术

✅ 博主简介&#xff1a;擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。 ✅成品或者定制&#xff0c;扫描文章底部微信二维码。 (1) 异构集群环境特征分析与训练任务智能分配机制 随着深度学习模型规模的不断扩大…

同一篇论文,知网5%,维普30%,为什么

维普AIGC检测高&#xff1f;6款工具帮你降到合格线 TL;DR&#xff1a;维普AIGC检测算法和知网不同&#xff0c;很多知网能过的工具在维普可能过不了。实测对维普效果最好的是嘎嘎降AI&#xff08;67%→9%&#xff09;&#xff0c;其次是比话降AI&#xff08;60%→12%&#xff0…

基于深度学习的油气知识图谱平台

✅ 博主简介&#xff1a;擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。✅成品或者定制&#xff0c;扫描文章底部微信二维码。(1) 油气领域实体关系数据集构建与预处理方法知识图谱作为一种结构化的知识表示方式&…

基于贝叶斯深度学习的雷达有源干扰识别方法

✅ 博主简介&#xff1a;擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。 ✅成品或者定制&#xff0c;扫描文章底部微信二维码。 (1) 雷达干扰信号建模与数据集制备方法 雷达系统在复杂电磁环境中面临着各种有源干…

同一篇论文,维普AI率67%→9%,我是怎么做到的

维普AIGC检测高&#xff1f;6款工具帮你降到合格线 TL;DR&#xff1a;维普AIGC检测算法和知网不同&#xff0c;很多知网能过的工具在维普可能过不了。实测对维普效果最好的是嘎嘎降AI&#xff08;67%→9%&#xff09;&#xff0c;其次是比话降AI&#xff08;60%→12%&#xff0…

维普AIGC检测怎么降?照这个流程来

维普AIGC检测高&#xff1f;6款工具帮你降到合格线 TL;DR&#xff1a;维普AIGC检测算法和知网不同&#xff0c;很多知网能过的工具在维普可能过不了。实测对维普效果最好的是嘎嘎降AI&#xff08;67%→9%&#xff09;&#xff0c;其次是比话降AI&#xff08;60%→12%&#xff0…

基于深度学习的人机协同产品造型仿生设计

✅ 博主简介&#xff1a;擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。✅成品或者定制&#xff0c;扫描文章底部微信二维码。(1) 基于深度生成模型的产品造型仿生融合方法仿生设计是产品创新的重要途径&#xff…

基于STM32智能门禁锁系统设计与实现

基于STM32智能门禁锁系统设计与实现摘要随着物联网技术的快速发展和智能家居需求的日益增长&#xff0c;传统门锁已难以满足现代生活对安全性与便捷性的要求。本文设计了一种基于STM32F103C8T6单片机的智能门禁锁系统&#xff0c;集成指纹识别、密码输入、RFID卡感应三种解锁方…