大家好,我是小杨,一个写了6年前端的老兵。今天要聊一个听起来高级但其实很接地气的概念------高阶组件(HOC)和高阶函数(HOF) 。
你是不是经常听到这两个词,但总觉得有点模糊?
- 高阶组件 和 高阶函数 到底有什么区别?
- 它们能解决什么问题?
- 为什么 React 官方推荐用 Hooks 替代 HOC?
别急,咱们用最直白的语言 + 实战代码,一次性讲清楚!
1. 高阶函数(HOF):函数的超级加工厂
什么是高阶函数?
高阶函数(Higher-Order Function)是指:
✅ 接收函数作为参数
✅ 或者返回一个新函数
举个🌰:
js
// 高阶函数示例:接收函数,返回增强版函数
function withLogging(fn) {
return function (...args) {
console.log("函数被调用了,参数是:", args);
const result = fn(...args);
console.log("函数执行结果:", result);
return result;
};
}
// 普通函数
function add(a, b) {
return a + b;
}
// 用高阶函数增强
const addWithLogging = withLogging(add);
addWithLogging(2, 3);
// 输出:
// 函数被调用了,参数是:[2, 3]
// 函数执行结果:5
实际应用场景:
- 防抖(debounce) / 节流(throttle)
- Redux 的
connect
(没错,它也是高阶函数!) - React 的
useCallback
/useMemo
(底层依赖函数记忆化)
2. 高阶组件(HOC):组件的超级增强版
什么是高阶组件?
高阶组件(Higher-Order Component)是指:
✅ 接收一个组件,返回一个新组件
✅ 用于复用组件逻辑(比如权限控制、日志记录)
举个🌰:
js
// 高阶组件:给组件添加「点击计数」功能
function withClickCounter(WrappedComponent) {
return function EnhancedComponent(props) {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
};
return (
<div onClick={handleClick}>
<WrappedComponent {...props} clickCount={count} />
</div>
);
};
}
// 普通组件
function MyButton({ clickCount }) {
return <button>我被点了 {clickCount} 次</button>;
}
// 用高阶组件增强
const SuperButton = withClickCounter(MyButton);
// 使用
function App() {
return <SuperButton />;
}
实际应用场景:
- 权限控制 (如:
withAuth(Component)
) - 数据注入 (如:
withUserData(Component)
) - 日志记录 (如:
withLogger(Component)
)
3. 高阶组件 vs 高阶函数:到底用哪个?
对比点 | 高阶函数(HOF) | 高阶组件(HOC) |
---|---|---|
作用对象 | 函数 | React 组件 |
主要用途 | 增强函数逻辑 | 增强组件逻辑 |
React 生态 | 通用(JS 概念) | React 特有 |
Hooks 替代方案 | useCallback / useMemo |
自定义Hook (更推荐) |
React 官方现在更推荐用 Hooks 替代 HOC,因为:
- HOC 容易形成嵌套地狱 (
withA(withB(withC(Component)))
) - Hooks 更直观,逻辑复用更灵活
4. 实战:用自定义Hook替代高阶组件
刚才的 withClickCounter
可以用 Hook 改写:
js
// 自定义Hook:useClickCounter
function useClickCounter() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
};
return { count, handleClick };
}
// 普通组件 + Hook
function MyButton() {
const { count, handleClick } = useClickCounter();
return <button onClick={handleClick}>我被点了 {count} 次</button>;
}
// 使用
function App() {
return <MyButton />;
}
优点:
- 没有嵌套,代码更清晰
- 逻辑复用更灵活(一个组件可以用多个 Hook)
5. 总结:如何选择?
✅ 如果你在操作函数 (如防抖、缓存计算)→ 用高阶函数(HOF)
✅ 如果你在增强React组件 → 优先用自定义Hook,其次才是HOC
❌ 避免过度嵌套HOC(否则调试会疯掉!)
⭐ 写在最后
请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.
✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式
✅ 认为我部分代码过于老旧,可以提供新的API或最新语法
✅ 对于文章中部分内容不理解
✅ 解答我文章中一些疑问
✅ 认为某些交互,功能需要优化,发现BUG
✅ 想要添加新功能,对于整体的设计,外观有更好的建议
✅ 一起探讨技术加qq交流群:906392632
最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!