HOC / Render Props & Hooks 都是代码复用的方式, 但是三者的区别和应用场景又分别是什么?
Render Props
Render Props, 在 React 组件之间使用一个值为函数的 prop 共享代码的技术(父子之间的信息传递); render prop 是一个用于告知组件需要渲染什么内容的函数 prop; 具有 render prop 的组件接受一个函数, 该函数返回一个 react 元素并调用它而不是实现自己的渲染逻辑
1 | // 先将 withRenderProps 封装为一个 Component |
HOC
HOC(Higher-Order-Component) 高阶组件, 是 React 中用于复用组件逻辑的一种技巧, 自身不是 React API 的一部分, 它是一种基于 React 的组合特性而形成的设计模式; 是一个参数为组件, 返回值为新组件的函数, 这么做是为了增强 (enhance), 如装饰、添加行为、添加逻辑等
1 | // hoc 的定义及使用 |
- 使用 HOC 解决横切关注点(Cross-Cutting Concerns)问题: 当代码逻辑大部分实现都是一样的, 且调用的地方比较多, 需要抽象出来, 在一个地方定义这个逻辑, 并在许多组件之间共享它
注意: HOC 不会修改传入的组件, 也不会使用继承来复制其行为, 相反, HOC 通过将组件包装在容器组件中来组成新组件, HOC 是纯函数, 没有副作用
- 不要改变原始组件, 使用组合: HOC 不应该修改传入组件, 而是应该使用组合的方式, 通过将组件包装在容器组件中实现功能
- 约定: 将不相关的 props 传递给被包裹的组件
- 约定: 最大化可组合性
- 约定: 包装显示名称方便调试
注意:
- 不要在 render 方法中使用 HOC
- 务必复制静态方法
- Refs 不会被传递
1 | // 封装成一个函数 withHOC, 这个函数返回一个新的 Component |
Hooks
Hooks
1 | // 封装成 useHooks, 在其他地方可以调用 useHooks |
总结
- Render Props: 可以在树状 VDOM 的渲染流程上有更多的自由度, 可以根据父组件提供的数据进行动态渲染; 适合有明确父子关系的场景
- HOC: 适合用来做注入, 并且生成一个新的可复用组件, 也适合用来做插件
- Hooks: 可以优化 render 的前置逻辑处理(提取复用逻辑), 也适合用于取代 class extend 的大部分用例
就像 async/await 将 Promise 的 Callback Hell 解决了, 将异步编程思维变成了同步变成思维; HOC & Render Props 容易产生 Wrapper Hell 问题, 而 Hooks 则解决了这一问题, 将”面向生命周期编程“变成了”面向业务逻辑编程“