Skip to content

高阶组件解决什么问题? ​

高阶组件是一个函数,接收组件,返回新组件。用来复用和展示无关的逻辑,例如注入数据、权限或埋点。Hooks 能表达的复用,优先用自定义 Hook,少包一层组件。

原理 ​

jsx
function withUser(Comp) {
  return function UserContainer(props) {
    const user = useUser()
    return <Comp {...props} user={user} />
  }
}

约定:把其余 props 原样传下去;给返回的组件起 displayName,方便调试;不要在渲染函数里创建高阶组件,那会每次都是新的组件类型,状态被清空。

反向继承(返回的组件 extends 传入的组件)会依赖对方的 render 结构,脆弱,不要用。

Hooks 的问题是逻辑复用要调用 Hook,不能在条件里调用。高阶组件的问题是层级变深、props 来源不清楚。一个权限判断如果只是早返回,用组合:<Can permission="edit">{children}</Can>,比包一层 HOC 更直接。见 权限控制。

追问 ​

和 render props 怎么选?

render props 把渲染函数当参数传进来,数据流看得见,但嵌套深。自定义 Hook 把数据留在调用它的组件里,通常更合适。HOC 还适合在不能改组件内部、只能在外面包一层的时候。

ref 会丢吗?

包一层之后,外面的 ref 指向包装组件,不是原组件。需要往下传时用 forwardRef。React 19 的函数组件可以把 ref 当 prop,包装层仍要自己决定传不传。

易错点 ​

  • 多个 HOC 都注入同名 prop,后面的静默覆盖前面的。
  • 在 HOC 里复制静态方法却漏了,外部拿不到 getDerivedStateFromProps 这类静态成员。
  • 为了复用十几行逻辑套三层 HOC,调用栈很难读。

相关 ​