type
status
date
slug
summary
tags
category
icon
password
React HOC VS Hooks
需要注意的是,HOC 主要用于类组件,而随着React 16.8 版本引入Hooks 特性以来,官方更加推崇使用Hooks来处理组件逻辑,Hooks使我们也可以在函数式组件中添加额外的功能,如状态管理、生命周期方法等。至此,HOC和Hooks都可以实现组件的逻辑抽象,达到复用或组织代码的目的。在现代的 React 应用中,很多情况下会使用 Hooks 来实现组件逻辑,因为它更简洁、直观,且更适用于函数组件。
不同:
HOC 使用的是函数包装组件的方式,而 Hooks 是在函数组件内部调用的特殊函数,两者实现方式和适用场景也不同。
Hooks的优势:
HOC相比较Hooks而言,可能会出现多层嵌套的情况,导致代码结构变得复杂,Hooks使得组件逻辑可以在同一层级上组织,避免了嵌套的问题。
以下来介绍一下什么是HOC,以及现在在React中,哪些地方适合用到这种技巧。
React HOC
高阶组件就是一个函数,且该函数接受一个组件作为参数,并返回一个包装原始组价的新组件。
高阶组件是React中一种用于组件复用的技巧,是一种基于React的组合特征而形成的设计模式
HOC希望解决的问题
- 代码复用: 批量对原有组件进行加工,包装处理
- 横切关注点(Cross-Cutting Concerns): 有些功能在应用中可能是横切的,比如日志记录、权限控制、分析等。通过使用 HOC,你可以将这些横切关注点的逻辑从组件中提取出来,使组件更专注于其核心功能。
- 状态逻辑的提取: 在 React 类组件中,状态逻辑(state logic)通常分散在多个生命周期方法中,这可能导致代码变得复杂。通过使用 HOC,你可以将状态逻辑抽象到单独的组件中,使原始组件更专注于 UI 渲染。
- 赋能组件: HOC 有一项独特的特性,就是可以给被 HOC 包裹的业务组件,提供一些拓展功能,比如说额外的生命周期,额外的事件,但是这种 HOC,可能需要和业务组件紧密结合。典型案例
react-keepalive-router
中的keepaliveLifeCycle
就是通过 HOC 方式,给业务组件增加了额外的生命周期。
- 动态组件: HOC 允许你在运行时动态生成组件,可以对原来的组件进行
条件渲染
,节流渲染
,懒加载
等功能,典型代表作react-redux
中connect
和dva
中dynamic
组件懒加载。 - HOC的控制渲染,可用于权限隔离、懒加载、延时加载、节流渲染(优化性能)等场景
HOC的实现
React 中认为:HOC 不会修改传入的组件,也不会使用继承来复制其行为(继承会导致组件之间高度耦合,不利于代码维护,不推荐),主要是实现是通过包装传入的组件,在其基础上加入一些额外的操作,不对传入组件造成副作用,而是进行正向的属性代理:
也可以使用自定义的 hooks 来实现一个类似 HOC 的功能
注意:
- 自定义HOC组件一般以
with
开头命名,自定义 Hooks 是一个函数,以use
开头
- HOC 组件 withLogger 和包装组件之间只通过 props 进行通信
HOC应该遵循的约定
HOC 主要是为组件添加特性,所以自身不应该大幅改变约定。HOC 返回的组件与原组件应保持类似的接口。
- HOC 应该透传与自身无关的 props
- 最大化可组合性,HOC 通常可以接收多个参数,一个是被包裹的组件,一个是用于指定组件的数据依赖
- 遵循命名规范,让人一眼就知道这是一个HOC
HOC的注意事项
- Refs 不会被传递,如果将 ref 添加到 HOC 的返回组件中,则 ref 引用指向容器组件,而不是被包装组件。这个问题的解决方案是通过使用
React.forwardRef
API
- render中不要声明HOC,会导致子树每次渲染都会进行卸载,和重新挂载的操作,该组件及其所有子组件的状态丢失
适合的使用模式
1️⃣ 权限认证
2️⃣ 日志记录
3️⃣ 定制化样式和主题
实践
更多案例可看
hoc-example
BlueBaidu • Updated Nov 24, 2023
- 作者:NotionNext
- 链接:https://mia.missz.top//article/2046db37-8986-4b03-9472-ea050f10d5ae
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章