5.5 复用抽象:HOC、混入与自定义 Hook


5.5 复用抽象:HOC、混入与自定义 Hook

本节摘要:当多个组件共用一段逻辑,就要决定"用哪种抽象抽走它"。高阶组件(HOC)、混入(Mixins)、自定义 Hook、组合式函数四套方案解决同一问题,却在可读性、来源可追溯、作用域隔离上高下立判。本节回到"比稿现场",把四套方案逐场评审,给出新时代的倾向。

本节阅读目标
阅读完本节,你应当能够:

  1. 说出四套抽象分别解决什么、怎么写。
  2. 指出混入在高阶组件上为何容易被弃用。
  3. 对给定复用场景,选出更符合当下工程实践的做法。

一、同一个问题,四份答卷

"我想让多个组件共享一段逻辑"。

高阶组件(Higher-Order Component):一个函数,接收一个组件,返回一个被装饰过的组件。React 传统方案。

function withLogging(Wrapped) { return function (props) { return <Wrapped {...props} />; }; }

混入(Mixins):把一组选项/数据合并注入组件,Vue 2 时代常用,Vue 3 已倾向弃用。

const loggerMixin = { methods: { log(msg) { console.log(msg); } }, };

自定义 Hook:React 以 use 开头的函数,把状态与副作用抽成可复用单元。

function useCounter() { const [count, setCount] = useState(0); const inc = () => setCount((c) => c + 1); return { count, inc }; }

组合式函数:Vue Composition API 里以 use 开头的函数,把响应式逻辑抽走。

function useCounter() { const count = ref(0); const inc = () => { count.value += 1; }; return { count, inc }; }

前两个更像"装饰/合并",后两个更像"组合/函数化"。这条演化线的终点是:把状态与逻辑组织成可复用的函数

二、每套怎么评审

  • HOC:包装灵活性高,但嵌套过多会形成"组件地狱",且包装层的 props 冲突来源难查。
  • 混入:合并来源不可追溯,多个混入优先级与冲突暗藏隐患,诊断难。
  • 自定义 Hook:React 推荐,来源可溯、表现如普通函数,组合天然。
  • 组合式函数:Vue 推荐,把响应式逻辑函数化,与 Hook 思路一致。

结论在 React 与 Vue 各自社区已经成为共识:现代工程几乎都用自定义 Hook / 组合式函数,HOC 留给历史或特定封装,混入基本弃用(Vue 3 也退出主推)。

三、四表对照

方案 框架 形式 可追溯 现状
HOC React 包装组件 旧代码常见
混入 Mixins Vue2 历史 合并选项 已倾向弃用
自定义 Hook React use 开头函数 推荐
组合式函数 Vue 组合函数 推荐

四、图:复用抽象的演进与新一代选择

图:四种复用抽象比稿一览

图:四种复用抽象比稿一览

五、比稿结论怎么写

当评审"这段通用上传逻辑怎么复用"时,把四套方案摆上桌:HOC 会让组件嵌套加深、混入来源不明,而自定义 Hook / 组合式函数把状态和动作封进一个可读函数,来源一目了然、还能组合。用"能读、能查、能组合"三个词打分,Hook / 组合式函数以绝对优势胜出。这套表达,正是"比稿现场"要训练的判断力。

五·一、同一段"上传进度"逻辑,两代方案的分野

比稿不能停在口号,落到代码才见真章。假设要在一块通用逻辑里维护"上传进度百分比"。用自定义 Hook 的写法是:

function useUpload() { const [progress, setProgress] = useState(0); const start = () => setInterval(() => setProgress((p) => Math.min(p + 10, 100)), 300); return { progress, start }; }

组件里一行引进来用,进度是谁的样子、谁在变,函数名 + setter 一目了然,还能被别的 Hook 自由组合。这是"组合函数"的典型面目:像一个普通函数,但内部携带状态与副作用,源代码直接可查。

相对的,若用混入实现同一件事,progressstart 会从某个匿名 mixin 悄悄注入组件,新旧值对比、优先级冲突都在代码外发生——你读组件时根本无从判断"这个 progress 从哪来"。"来源可追溯"四字差异,才是后者在比稿里被淘汰的根因:功能都能做,但可维护性决定了谁配活到版本二。这条判断,是所有复用抽象评审里最该被记住的一句话。

六、常见坑

  • 混入优先级之谜:多个混入同名方法谁先谁后难记,避免用它来做需要覆盖逻辑的共享。
  • HOC 透传 props 丢失:包装层忘展开原始 props,子组件拿不到本应收到的数据。
  • 自定义 Hook 违反铁律:在条件/循环里调用,破坏顺序导致时好时坏。

一句话收束:抽象也是负债

复用抽象用得好是省力杠杆,但每个抽出来的"复用单元"本身也要被人读懂、被后续维护,这份成本就是抽象欠下的债。判断一份逻辑要不要抽,可以把你的目标折射成两问:这段代码真的有第二个使用方吗?抽出来后,使用者是不是明显比复制粘贴更省心?两问都答"是",抽象就是正收益;否则它就是为假设中的复用提前付费。回到比稿现场那句话——能读、能查、能组合,永远比"招式多"更值钱。

本节要点回顾

  • 四方案:HOC、混入、自定义 Hook、组合式函数,同心不同路。
  • 演进终点:将状态与逻辑组织成可复用函数。
  • 评审三词:能读、能查、能组合。
  • 新代码倾向:Hook / 组合式函数,HOC 留给历史封装。

组件之间的协作与复用这一章画上句号。下一章我们把视角拉远到整个应用:状态管理与路由导航,解决"多个页面共享状态、页面之间如何导航 以及 如何异步取数"这三大工程题。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U