从 Angular 和 React 看编程范式演进:OOP 与 FP 的深度对比
一、直观体验:两种框架的组件交互方式
Angular(OOP 风格)
<!-- 父组件模板 -->
<app-layout [selected]="'Expedientes'" #appLayout>
<div class="form-field" *ngIf="appLayout.isEntity()">
<!-- 条件渲染内容 -->
</div>
</app-layout>
特点分析:
- 使用
[selected]属性向下传递数据 - 通过
#appLayout模板变量直接获取子组件实例 - 直接调用子组件的公共方法
isEntity()
React(FP 风格)
// 子组件 - Layout.js
const Layout = forwardRef(({ selected }, ref) => {
const [user, setUser] = useState(null);
// 显式暴露方法给父组件
useImperativeHandle(ref, () => ({
isEntity: () => user && 'cif' in user
}));
return <div>{/* 组件内容 */}</div>;
});
// 父组件
const Parent = () => {
const layoutRef = useRef();
return (
<Layout selected="Expedientes" ref={layoutRef}>
{layoutRef.current?.isEntity() && (
<div className="form-field">{/* 条件内容 */}</div>
)}
</Layout>
);
};
特点分析:
- 通过
selectedprop 向下传递数据 - 使用
useRef+forwardRef获取子组件引用 - 必须显式声明暴露的方法(
useImperativeHandle)
二、核心差异对比
| 特性 | Angular (OOP) | React (FP) |
|---|---|---|
| 组件本质 | 类实例 | 函数闭包 |
| API 暴露 | 自动公开公共成员 | 需显式声明暴露内容 |
| 状态管理 | 类属性 + 变更检测 | useState + 不可变更新 |
| 代码复用 | 继承 + 服务 | 自定义 Hook + 组合 |
三、设计哲学深度解析
1. Angular 的面向对象思维
// 典型的 Angular 组件类
@Component({
selector: 'app-user',
template: `...`
})
export class UserComponent {
@Input() user: User; // 输入属性
@Output() selected = new EventEmitter(); // 输出事件
public isEntity(): boolean { // 公共方法
return this.user && 'cif' in this.user;
}
}
OOP 特点:
- 组件即类实例,天然拥有公共 API
- 通过装饰器声明元数据(@Component、@Input 等)
- 依赖注入系统管理组件依赖
2. React 的函数式思维
// 典型的 React 函数组件
const UserComponent = ({ user, onSelect }) => {
// 状态管理通过 Hook
const [isActive, setIsActive] = useState(false);
// 副作用通过 Hook 处理
useEffect(() => {
// 副作用逻辑
}, [user]);
// 渲染函数返回 UI
return (
<div onClick={() => onSelect(user)}>
{user.name}
</div>
);
};
FP 特点:
- UI = f(state):UI 是状态的函数
- 不可变数据流:状态更新创建新对象而非修改原对象
- 组件组合优于继承