在 React 开发中,Hook 和 高阶组件(HOC) 都是用来复用组件逻辑的方案,但它们有不同的使用场景和优缺点。下面是两者的对比和使用建议。
一、Hook 的适用场景
什么时候使用 Hook?
- 需要共享状态或副作用逻辑,但不想引入新的组件层级。
- 逻辑复杂且与生命周期密切相关(如
useEffect
)。 - 希望保持组件结构简洁,避免嵌套地狱(HOC 容易造成多层包裹)。
- 函数组件中需要访问 React 特性(如 state、context、ref、生命周期等)。
- 自定义可复用的逻辑模块(例如:
useFetch
, useForm
, useLocalStorage
等)。
示例:
const useGetDataSource = (api) => {const [data, setData] = useState([]);
useEffect(() => {
fetch(api).then(res => res.json()).then(setData);
}, [api]);
return data;
};
优点:
- 更直观地组织逻辑,将相关代码放在一起。
- 避免 HOC 带来的“嵌套地狱”。
- 支持组合、拆分逻辑,提高可维护性。
二、高阶组件(HOC)的适用场景
什么时候使用 HOC?
- 需要增强组件功能而不修改其内部实现(如权限控制、日志埋点)。
- 多个组件都需要相同的渲染逻辑或 props 注入。
- 兼容类组件时的逻辑复用方式(类组件不能使用 Hook)。
- 对组件进行包装装饰(如添加布局、样式、数据注入等)。
示例:
function withLoading(WrappedComponent) {
return function WithLoading(props) {
if (!props.data)
return <div>Loading...</div>;
return <WrappedComponent {...props} />;};}
优点:
- 对组件封装性强,适合跨项目复用。
- 可以包裹任意类型的组件(包括类组件和函数组件)。
- 适用于组件级别的增强逻辑(如权限校验、错误边界等)。
不推荐使用的情况
方式 | 不推荐场景 |
---|
Hook | 在类组件中使用(不支持)、用于组件间 UI 复用 |
HOC | 逻辑复杂度高时(难以调试和追踪)、频繁嵌套导致 props 冲突 |
Hook vs HOC 对比表
特性 | Hook | 高阶组件(HOC) |
---|
支持类组件 | ❌ 否 | ✅ 是 |
可读性 | ✅ 更清晰 | ⚠️ 嵌套深时难读 |
组合能力 | ✅ 强 | ⚠️ 容易命名冲突 |
逻辑复用粒度 | ✅ 细粒度 | ✅ 粗粒度 |
使用门槛 | 中等(需理解闭包、依赖项) | 较低 |
是否新增组件层级 | ❌ 否 | ✅ 是 |
总结:怎么选?
场景 | 推荐方式 |
---|
函数组件内共享逻辑(如请求、状态管理) | ✅ Hook |
类组件需要复用逻辑 | ✅ HOC |
组件级别增强(如权限包裹、加载状态) | ✅ HOC |
想要避免组件嵌套 | ✅ Hook |
多个组件共用一套副作用逻辑 | ✅ Hook |
兼容老旧项目或第三方库 | ✅ HOC |
💡 补充建议:
- 优先使用 Hook:React 官方推荐使用 Hook 来组织逻辑,它更符合现代 React 的开发模式。
- HOC 作为补充:在某些特定场景下(如权限控制、路由配置、错误边界),HOC 依然有其优势。
- 结合使用也 OK:你也可以在 HOC 中使用 Hook,两者并不冲突。
如果你正在写一个新组件,并且是函数组件,那么优先考虑用 Hook;如果是在老项目中维护类组件,或者需要做组件级增强,则可以考虑使用 HOC。