类组件和函数组件究竟有啥不同?React 的两种写法你选对了吗?

类组件VS函数组件:React的两种灵魂你选对了吗?

当React 16.8在2019年推出Hooks时,整个前端世界仿佛经历了一场"傅里叶变换"——原本需要类组件才能实现的状态管理、生命周期等核心功能,现在通过函数组件就能轻松实现。这种转变不仅带来了代码量的锐减,更掀起了React开发范式从面向对象到函数式编程的深刻变革。

一、DNA级别的写法差异

1. 组件定义方式

类组件像一个精心设计的机器:

JavaScript
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  //...
}

函数组件则如同数学公式般简洁:

JavaScript
function Clock() {
  const [date, setDate] = useState(new Date());
  //...
}

2. 生命周期管理

类组件采用声明周期方法

  • componentDidMount()
  • shouldComponentUpdate()
  • componentWillUnmount()

函数组件使用useEffect Hook

JavaScript
useEffect(() => {
  // 组件挂载
  return () => {
    // 组件卸载
  };
}, []);

二、核心能力对比

1. 状态管理

类组件通过this.state和setState管理状态,存在状态合并特性,但容易遇到this指向问题。

函数组件使用useState Hook,每个状态变量都是独立存储,依靠闭包特性保持数据隔离。

2. 逻辑复用模式

类组件通过HOC(高阶组件)或Render Props实现逻辑复用,容易产生嵌套地狱

函数组件使用自定义Hook,如useWindowSize这样的Hook可以像乐高积木般复用。

三、性能与调试对比

1. 打包体积差异

函数组件相比类组件平均减少约30%的打包体积,因为不需要处理类继承等复杂机制。

2. 热更新支持

函数组件在热更新时能保持状态,而类组件经常需要手动刷新才能获取最新状态。

3. 调试友好度

函数组件的闭包环境让React DevTools可以精确追踪每个状态的变更来源,而类组件的状态变更往往需要手动断点调试。

四、迁移指南:从类到函数的艺术

  1. 状态迁移:将this.state改写为useState
  2. 生命周期转化:用useEffect替代componentDidMount/Update
  3. 实例方法:使用useRef保存可变值
  4. 高阶组件:改写成自定义Hook

五、如何选择:新项目的决策树

根据我们团队在电商中台项目的实践经验:

  • 选择函数组件当:
    • 需要快速原型开发
    • 涉及复杂状态逻辑
    • 要求高性能列表渲染
  • 保留类组件当:
    • 维护遗留代码
    • 需要Error Boundaries
    • 存在大量生命周期强依赖

在2023年的React生态中,函数组件+Hook已成为主流选择。但这并不意味着类组件要被淘汰——就像摄影不会因为数码相机的出现就完全抛弃胶片,关键是要理解两者的特性,在合适的场景选择恰当的工具。无论是"淘宝种草文"式的类组件,还是"感受文"式的函数组件,真正优秀的开发者都应该掌握这两种表达方式,写出既高效又优雅的React代码。