常见的8个问题带你进阶 React
xsobi 2024-12-10 21:37 1 浏览
作者:广州peen
转发链接:https://mp.weixin.qq.com/s/dKuXK4pf8Eo2nEjOLW9qYg
前言
本篇文章会列举 react 的所有常见面试问题. 并附上详细解答.如果你想更深入的了解底层原理, 可到文末的建议阅读中查找.
问题列表
- 高阶组件(HOC) , render props 以及 hook 的对比和用处.
- 虚拟 DOM 是什么?
- react diff 原理, 如何从 O(n^3) 变成 O(n)
- 为什么要使用 key , 有什么好处?
- jsx 的原理
- 自定义的 React 组件为何必须大写
- setState 什么时候是同步,什么时候是异步?
- React 如何实现自己的事件机制?
- React 事件和原生事件有什么区别
- 聊一聊 fiber 架构
- React 事件中为什么要绑定 this 或者 要用箭头函数, 他们有什么区别
如果以上的问题你都懂的话, 那么你可以关闭这个网页了.
一. 高阶组件(HOC) , render props 以及 hook 的对比和用处.
详细的内容请见另一篇文章: 面试官: 谈一谈 HOC、Render props、Hooks
二. 虚拟 DOM 是什么?
在 React 中, React 会先将代码转换成一个 JS 对象, 然后再将这个 JS 对象转换成真正的 DOM. 这个 JS 对象就是所谓的虚拟 DOM.
它可以让我们无须关注 DOM 操作, 只需要开心地编写数据,状态即可.
三. react diff 原理, 如何从 O(n^3) 变成 O(n)
- 为什么是 O(n^3) ?
从一棵树转化为另外一棵树,直观的方式是用动态规划,通过这种记忆化搜索减少时间复杂度。由于树是一种递归的数据结构,因此最简单的树的比较算法是递归处理。确切地说,树的最小距离编辑算法的时间复杂度是 O(n^2m(1+logmn)), 我们假设 m 与 n 同阶, 就会变成 O(n^3)。
推荐阅读(为什么是 O(n^3))[1]:
- react diff 原理
简单的来讲, react 它只比较同一层, 一旦不一样, 就删除. 这样子每一个节点只会比较一次, 所以算法就变成了 O(n).
对于同一层的一组子节点. 他们有可能顺序发生变化, 但是内容没有变化. react 根据 key 值来进行区分, 一旦 key 值相同, 就直接返回之前的组件, 不重新创建.
这也是为什么渲染数组的时候, 没有加 key 值或者出现重复key值会出现一些奇奇怪怪的 bug .
除了 key , 还提供了选择性的树渲染。开发人员可以重写 shouldComponentUpdate 提高 diff 的性能。
推荐阅读(diff 原理)[2]
四. jsx 的原理
<div>Hello ConardLi</div>
实际上, babel 帮我们将这个语法转换成
React.createElement('div', null, `Hello ConardLi`)
自定义组件必须大写的原因.
babel 在编译的过程中会判断 JSX 组件的首字母, 如果是小写, 则为原生 DOM 标签, 就编译成字符串. 如果是大写, 则认为是自定义组件. 编译成对象.
为什么以下代码会报错?
return (<a></a><a></a>)
同样的, 因为我们是按照 React.createElement() 来创建组件, 所以只能有一个根节点. 如果你想要使用 2 个平行的节点, 可以用 <></> 来包裹. <></> 会被编译成 <React.Fragment/>.
babel 转译如下:
自己动手玩一下转换, 加深印象吧~
babel 转换[3]
五. setState 什么时候是同步,什么时候是异步?
这里的“异步”不是说异步代码实现. 而是说 react 会先收集变更,然后再进行统一的更新.
setState 在原生事件和 setTimeout 中都是同步的. 在合成事件和钩子函数中是异步的.
在 setState 中, 会根据一个 isBatchingUpdates 判断是直接更新还是稍后更新, 它的默认值是 false. 但是 React 在调用事件处理函数之前会先调用 batchedUpdates 这个函数, batchedUpdates 函数 会将 isBatchingUpdates 设置为 true. 因此, 由 react 控制的事件处理过程, 就变成了异步(批量更新).
六. React 里面的事件机制.
我们先看看 冒泡捕获 的经典图:
在组件挂载的阶段, 根据组件生命的 react 事件, 给 document 添加事件 addEventListener, 并添加统一的事件处理函数 dispatchEvent.
将所有的事件和事件类型以及 react 组件进行关联, 将这个关系保存在一个 map 里. 当事件触发的时候, 首先生成合成事件, 根据组件 id 和事件类型找到对应的事件函数, 模拟捕获流程, 然后依次触发对应的函数.
如果原生事件使用 stopPropagation 阻止了冒泡, 那么合成事件也被阻止了.
React 事件机制跟原生事件有什么区别
- React 的事件使用驼峰命名, 跟原生的全部小写作区分.
- 不能通过 return false 来阻止默认行为, 必须明确调用 preventDefault 去阻止浏览器的默认响应.
推荐阅读(动画浅析 React 事件系统和源码)[4]
七. 什么是 React Fiber
背景: 由于浏览器它将 GUI 描绘,时间器处理,事件处理,JS 执行,远程资源加载统统放在一起。如果执行 js 的更新, 占用了太久的进程就会导致浏览器的动画没办法执行,或者 input 响应比较慢。
react fiber 使用了 2 个核心解决思想:
- 让渲染有优先级
- 可中断
React Fiber 将虚拟 DOM 的更新过程划分两个阶段,reconciler 调和阶段与 commit 阶段. 看下图:
一次更新过程会分为很多个分片完成, 所以可能一个任务还没有执行完, 就被另一个优先级更高的更新过程打断, 这时候, 低优先级的工作就完全作废, 然后等待机会重头到来.
调度的过程
requestIdleCallback
首先 react 会根据任务的优先级去分配各自的过期时间 expriationTime . requestIdleCallback 在每一帧的多余时间(黄色的区域)调用. 调用 channel.port1.onmessage , 先去判断当前时间是否小于下一帧时间, 如果小于则代表我们有空余时间去执行任务, 如果大于就去执行过期任务,如果任务没过期. 这个任务就被丢到下一帧执行了.
由于 requestIdleCallback 的兼容性问题, react 自己实现了一个 requestIdleCallback
推荐阅读(司徒正美 React Fiber 架构)[5]
八. React 事件中为什么要绑定 this 或者要用箭头函数?
事实上, 这并不算是 react 的问题, 而是 this 的问题. 但是也是 react 中经常出现的问题. 因此也讲一下
<button type="button" onClick={this.handleClick}>Click Me</button>
这里的 this . 当事件被触发且调用时, 因为 this 是在运行中进行绑定的.his 的值会回退到默认绑定,即值为 undefined,这是因为类声明和原型方法是以严格模式运行。
我们可以使用 bind 绑定到组件实例上. 而不用担心它的上下文.
因为箭头函数中的 this 指向的是定义时的 this,而不是执行时的 this. 所以箭头函数同样也可以解决.
推荐React 学习相关文章
《这就是你日思夜想的 React 原生动态加载「值得收藏」》
《手把手教你从Mixin深入到HOC再到Hook【React】》
《深入Facebook 官方React 状态管理器Recoil讲解》
《React源码分析与实现(一):组件的初始化与渲染「实践篇」》
《React源码分析与实现(二):状态、属性更新->setState「实践篇」》
《手把手教你10个案例理解React hooks的渲染逻辑「实践」》
《Vue 3.0 Beta 和React 开发者分别杠上了》
《手把手深入Redux react-redux中间件设计及原理(上)【实践】》
《手把手深入Redux react-redux中间件设计及原理(下)【实践】》
《为了学好 React Hooks, 我解析了 Vue Composition API》
《【React 高级进阶】探索 store 设计、从零实现 react-redux》
《深入浅出掌握React 与 React Native这两个框架》
《你需要的 React + TypeScript 50 条规范和经验》
《手把手教你深入浅出实现Vue3 & React Hooks新UI Modal弹窗》
《全平台(Vue/React/微信小程序)任意角度旋图片裁剪组件》
作者:广州peen
转发链接:https://mp.weixin.qq.com/s/dKuXK4pf8Eo2nEjOLW9qYg
相关推荐
- Android Studio 导入项目出现缺失解决
-
很多朋友安装好Androidstudio后准备试一把,但是导入项目的时候出现错误Cannotfindfile"...../project_name/settings.jar"这个错误是因为导入...
- 首个安卓12开发者预览版发布:隐私保护升级、更新UI、优化性能
-
来源:环球网2月20日消息,据engadget报道,来到二月,惯例也是谷歌发布安卓12开发者预览版的时候,以便于让开发者提前查看下一版安卓系统的新属性。谷歌工程副总裁戴夫·波尔克(DaveBurke...
- 推荐几个非常有用的开发工具之Android Studio插件
-
我们都知道Eclipse开发Android将在今年年底google不再继续提供相应的开发支持,转而开始强烈发展AndroidStudio,现在我就分享几款能帮助团队提升工作效率的几个Android...
- Android Studio下的应用性能优化总结-内存优化
-
上一篇文章总结的布局优化的问题,如果对布局优化不是很熟悉的,可以看一下AndroidStudido下的应用性能优化总结–布局优化,这周一直筹划总结一下内存优化的问题,因为现在对于应用优化的文章很...
- 安卓开发之环境搭建「图文教程」 安卓应用开发环境搭建
-
安卓(Android)是一种基于Linux的自由及开放源代码的操作系统。主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。接下来开始第一个安卓应用吧!需要用到的软...
- Android APP性能测试上篇--启动时长、内存
-
如图所示,列出了目前app主要的一些性能指标,以及对应使用的测试工具。普遍的app性能测试,主要是以下几类:启动时长、内存、cpu、FPS(app使用的流畅度)、GPU过度渲染、耗电、耗流、cras...
- AndroidStudio下的依赖管理 安卓依赖管理
-
在开发中用第三方库是很常见的事,如何在AndroidStudio下管理这些依赖呢?这就是这篇文章的目的。目录Maven/Ivy仓库依赖Module依赖aar文件依赖jar文件依赖例子完整代码一、Mav...
- 基于Android的师生学习交流平台:Android课程设计
-
基于Android的师生学习交流平台(Androidstudio毕业设计,Android课程设计)一、项目介绍系统分为学习资料,作业,师生交流,个人资料四大模块(1)学生端:新用户需要填写真实姓名,...
- Android Studio 贴士 - 综述#3 android studios
-
(点击上方公号,可快速关注)英文原文:http://www.developerphil.com/android-studio-tips-of-the-day-roundup-3注:文中链接皆为国外链接...
- Android 11 Developer Preview首次更新发布:修复诸多问题
-
此前在2月19日,谷歌放出了Android11DeveloperPreview(安卓11开发者预览版),并表示Beta版本将于5月份推出,最终发行版将于2020年Q3面世。如今距离Android...
- Android12 支持无线usb调试应用 安卓 usb调试
-
背景在android12版本中已经支持wifiusb调试了,再也不用查数据线了,下面主要说下连接步骤:1.在开发者启动无线调试...
- InstantRun原理--深度剖析AndroidStudio2.0
-
http://crash.163.com/#news/!newsId=8推荐理由AndroidStudio2.0开始支持InstantRun特性,使得在开发过程中能快速将代码变化更新到设...
- 集成开发环境Android Studio整合Gemini:可生成、补全代码
-
IT之家4月9日消息,谷歌近日发布新闻稿,宣布在AndroidStudio中集成Gemini1.0Pro,从而帮助开发人员更快、更好地写出代码。谷歌表示目前相关整合仍处于预览阶段,...
- Android studio 最新版本下Gradle的一些配置
-
当我们把Androidstudio版本更新到Bumblebee版本时,我们会发现创建新的项目时,有了一些改变。项目根目录下面的build.gradle变了:旧版本下的是这样子的:setting.gr...
- Android Studio最新版下载安装:Android Studio模拟器怎么启动
-
目录第一部分:AndroidStudio软件介绍...
- 一周热门
- 最近发表
-
- Android Studio 导入项目出现缺失解决
- 首个安卓12开发者预览版发布:隐私保护升级、更新UI、优化性能
- 推荐几个非常有用的开发工具之Android Studio插件
- Android Studio下的应用性能优化总结-内存优化
- 安卓开发之环境搭建「图文教程」 安卓应用开发环境搭建
- Android APP性能测试上篇--启动时长、内存
- AndroidStudio下的依赖管理 安卓依赖管理
- 基于Android的师生学习交流平台:Android课程设计
- Android Studio 贴士 - 综述#3 android studios
- Android 11 Developer Preview首次更新发布:修复诸多问题
- 标签列表
-
- grid 设置 (58)
- 移位运算 (48)
- not specified (45)
- patch补丁 (31)
- strcat (25)
- 导航栏 (58)
- context xml (46)
- scroll (43)
- element style (30)
- dedecms模版 (53)
- vs打不开 (29)
- nmap (30)
- webgl开发 (24)
- c 视频教程下载 (33)
- paddleocr (28)
- listview排序 (33)
- firebug 使用 (31)
- transactionmanager (30)
- characterencodingfilter (33)
- getmonth (34)
- commandtimeout (30)
- hibernate教程 (31)
- label换行 (33)
- curlpost (31)
- android studio 3 0 (34)