从 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 是状态的函数
- 不可变数据流:状态更新创建新对象而非修改原对象
- 组件组合优于继承
四、历史背景与演进趋势
为什么先有 Angular(OOP 风格)?
- 2000-2010 年代 Java/C# 背景开发者占主流
- OOP 是当时最熟悉的范式
- 类组件 + 依赖注入降低了后端开发者的学习门槛
React 为何后来居上?
// React 的简洁性示例
const App = () => {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
};
React 成功因素:
- 更简单的心理模型:UI 是状态的函数
- 更好的性能:虚拟 DOM 和精细的更新控制
- 更灵活的架构:函数组合优于类继承
现代框架的融合趋势
// Vue 3 组合式 API(受 React Hook 启发)
import { ref, computed } from 'vue';
export default {
setup() {
const count = ref(0);
const double = computed(() => count.value * 2);
return { count, double };
}
}
演进趋势:
- Angular 增加函数式特性
- Vue 3 引入组合式 API
- 所有框架都向更简单的函数式模型靠拢
五、实战场景对比
复杂状态管理
Angular(服务 + 类)
@Injectable({ providedIn: 'root' })
export class UserService {
private users = new BehaviorSubject<User[]>([]);
getUsers() { /* API 调用 */ }
addUser(user: User) {
// 可变更新(Angular 变更检测可处理)
const current = this.users.value;
current.push(user);
this.users.next(current);
}
}
React(Hook + 不可变更新)
const useUsers = () => {
const [users, setUsers] = useState([]);
const addUser = (newUser) => {
// 不可变更新
setUsers(prevUsers => [...prevUsers, newUser]);
};
return { users, addUser };
};
六、总结:选择哪种范式?
OOP(Angular)优势:
- 结构清晰,适合大型团队
- 强大的类型系统和工具支持
- 完整的解决方案(路由、状态管理等)
FP(React)优势:
- 更简单的心理模型
- 更灵活的代码组织方式
- 更好的性能优化可能性
最终建议:
- 大型企业级应用:Angular 的 OOP 结构提供更好的可维护性
- 快速迭代的产品:React 的 FP 模式提供更好的开发体验