网站首页 > 技术文章 正文
基于目前react应用的普遍性,小编整理了两个比较重要的知识点,下面一起跟大伙聊聊,希望能对大伙的理解有所帮助。
HOC 是什么?相比 mixins 有什么优点?
很多人看到高阶组件(HOC)这个概念就被吓到了,认为这东西很难,其实这东西概念真的很简单,我们先来看一个例子。
function add(a, b) { return a + b }
现在如果我想给这个 add 函数添加一个输出结果的功能,那么你可能会考虑我直接使用 console.log不就实现了么。说的没错,但是如果我们想做的更加优雅并且容易复用和扩展,我们可以这样去做:
function withLog (fn) { function wrapper(a, b) { const result = fn(a, b) console.log(result) return result } return wrapper } const withLogAdd = withLog(add) withLogAdd(1, 2)
其实这个做法在函数式编程里称之为高阶函数,大家都知道 React 的思想中是存在函数式编程的,高阶组件和高阶函数就是同一个东西。我们实现一个函数,传入一个组件,然后在函数内部再实现一个函数去扩展传入的组件,最后返回一个新的组件,这就是高阶组件的概念,作用就是为了更好的复用代码。
其实 HOC 和 Vue 中的 mixins 作用是一致的,并且在早期 React 也是使用 mixins 的方式。但是在使用 class 的方式创建组件以后,mixins 的方式就不能使用了,并且其实 mixins 也是存在一些问题的,比如:
- 隐含了一些依赖,比如我在组件中写了某个 state 并且在 mixin 中使用了,就这存在了一个依赖关系。万一下次别人要移除它,就得去 mixin 中查找依赖
- 多个 mixin 中可能存在相同命名的函数,同时代码组件中也不能出现相同命名的函数,否则就是重写了,其实我一直觉得命名真的是一件麻烦事。。
- 雪球效应,虽然我一个组件还是使用着同一个 mixin,但是一个 mixin 会被多个组件使用,可能会存在需求使得 mixin 修改原本的函数或者新增更多的函数,这样可能就会产生一个维护成本
HOC 解决了这些问题,并且它们达成的效果也是一致的,同时也更加的政治正确(毕竟更加函数式了)。
事件机制
React 其实自己实现了一套事件机制,首先我们考虑一下以下代码:
const Test = ({ list, handleClick }) => ({ list.map((item, index) => ( <span onClick={handleClick} key={index}>{index}</span> )) })
以上类似代码想必大家经常会写到,但是你是否考虑过点击事件是否绑定在了每一个标签上?事实当然不是,JSX 上写的事件并没有绑定在对应的真实 DOM 上,而是通过事件代理的方式,将所有的事件都统一绑定在了 document 上。这样的方式不仅减少了内存消耗,还能在组件挂载销毁时统一订阅和移除事件。
另外冒泡到 document 上的事件也不是原生浏览器事件,而是 React 自己实现的合成事件(SyntheticEvent)。因此我们如果不想要事件冒泡的话,调用 event.stopPropagation 是无效的,而应该调用 event.preventDefault。
那么实现合成事件的目的是什么呢?总的来说在我看来好处有两点,分别是:
- 合成事件首先抹平了浏览器之间的兼容问题,另外这是一个跨浏览器原生事件包装器,赋予了跨浏览器开发的能力
- 对于原生浏览器事件来说,浏览器会给监听器创建一个事件对象。如果你有很多的事件监听,那么就需要分配很多的事件对象,造成高额的内存分配问题。但是对于合成事件来说,有一个事件池专门来管理它们的创建和销毁,当事件需要被使用时,就会从池子中复用对象,事件回调结束后,就会销毁事件对象上的属性,从而便于下次复用事件对象。
小结
以上就是这次总结的react的两个比较重要的知识点,可能你会觉得有点少,但是如果你能真正的理解,再加上我之前的关于react的两篇文章,相信应付日常的开发是没有问题的。
猜你喜欢
- 2024-09-20 Vue.js常见的20道前端面试题及答案
- 2024-09-20 AI面试官:我能胜任React(二)(我能胜任这份工作吗)
- 2024-09-20 70个JavaScript知识点详细总结(上)【实践】
- 2024-09-20 ReactDOM.render和ReactDOM.createPortal的区别
- 2024-09-20 学会使用Vue JSX,一车老干妈都是你的
- 2024-09-20 字节P8大佬爆肝整理,一文带你梳理React面试题!
- 2024-09-20 2024前端面试真题之—VUE篇(2020web前端经典面试题 vue)
- 2024-09-20 JS事件绑定的常用方式实例总结(js事件绑定的四种方式)
- 2024-09-20 JavaScript 的基本术语大全(javascript的基本概念)
- 2024-09-20 React18内核探秘:手写React高质量源码迈向高阶开发(超清完结)
- 1514℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 563℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 508℃MySQL service启动脚本浅析(r12笔记第59天)
- 486℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 485℃启用MySQL查询缓存(mysql8.0查询缓存)
- 465℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 445℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 442℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)