一、前言
许多刚接触 React 的小伙伴经常发出疑问:阅读 React 17 之前的代码,很多都是采用面向对象编程(class 类组件)的方式,而到了 React 18 似乎大多转为函数式编程(function 函数组件),那么这两者又有什么异同点?我该选择哪种方式写代码呢?
本文我们将从不同角度分析两者在 React 中的应用,并通过代码片段展示其差异,同时讨论各自的优缺点。
二、类组件示例
组件编写
class UserComponent extends React.Component {
constructor(props) {
super(props);
this.state = { user: props.initialUser };
this.handleNameChange = this.handleNameChange.bind(this);
}
handleNameChange(event) {
const newUser = { ...this.state.user, name: event.target.value };
this.setState({ user: newUser });
}
render() {
return (
<div>
<input type="text" onChange={this.handleNameChange} value={this.state.user.name} />
<p>姓名:{this.state.user.name}</p>
</div>
);
}
}
组件使用
// 使用class组件
<UserComponent initialUser={{name: '张三'}} />
✔️ 优点
- 封装性:面向对象编程(OOP)中的类可以封装状态和行为,有助于模块化和抽象复杂逻辑。
- 继承与多态:通过继承和重写方法,可以实现代码复用和接口一致性。
- 生命周期方法:React 中的类组件提供了丰富的生命周期钩子,便于管理组件的创建、更新和销毁过程。
❌ 缺点
- 心智负担:过多的类层次结构可能导致代码难以理解和维护。
- 冗余:需要手动绑定 this 上下文或者使用类属性语法避免丢失作用域。
- 性能:相比于函数组件,类组件可能带来额外的性能开销,尤其是在大量使用时。
三、函数式组件+hook示例
组件编写
// 函数组件 + Hooks 示例
import React, { useState } from 'react';
function UserComponent({ initialUser }) {
const [user, setUser] = useState(initialUser);
const handleNameChange = (event) => {
const newUser = { ...user, name: event.target.value };
setUser(newUser);
};
return (
<div>
<input type="text" onChange={handleNameChange} value={user.name} />
<p>姓名:{user.name}</p>
</div>
);
}
组件使用
// 使用function组件
<UserComponent initialUser={{ name: '张三' }} />
✔️ 优点
- 简洁性:函数式编程(FP)更易于阅读和编写,尤其在结合 React Hooks 后,可以无需类就能管理状态和副作用。
- 可复用性:Hook 如 useState、useEffect 等提供了一种声明式的编程模型,能够轻松组合和复用逻辑。
- 性能优化:React 18 引入了并发模式,函数组件配合 Suspense 和新的调度机制能更好地利用资源,提升用户体验。
❌ 缺点
- 思维方式转变:对于习惯 OOP 开发的开发者来说,FP 可能需要一定时间适应,特别是对于如何管理共享状态和副作用。
- 大型应用管理:对于非常复杂的组件树,纯函数式编程可能需要更多的策略和技术(如 Redux、Context API)来组织全局状态。
四、异同点总结
通过上述二种组件编写方式可以看出,只是在编写组件时存在区别,而在使用组件时用的是相同的标签语法,因此理论上你也可以在同个项目中混合使用两种不同的组件编写方式。
五、总结
React 18 中并没有强制规定必须使用某种编程范式,实际开发中可以根据项目规模、团队协作和个人喜好灵活选择。函数式编程随着 React Hooks 的推出,已经成为了主流趋势,因为它鼓励更简洁、纯函数式的组件结构,降低了认知复杂度,并且更加符合现代前端架构的趋势。然而,面向对象编程仍然在某些特定场景下具有优势,比如需要利用类的特性进行更深度的封装和扩展时。
免费全栈笔记、教程,关注公众号:卢克代码社: