最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • React 面试简单知识点整理

    正文概述 掘金(夏天Summer)   2020-12-08   459

    前言

    平时都用 React开发 ,但说实话没怎么看过具体的知识点,最近在拉钩看了两门课程,觉得收获颇深,根据自己的一点浅显的理解整理了一点 React 的简单用来面试的知识点,其中很多自己都是一笔带过,课程里还有很多源码的解析,大伙可以自己购买来看

    课程还在持续更新,不得不说,非常香

    具体内容

    1. 简单介绍下 React?

    定义:

    以组件化的思想,用于构建用户界面的JavaScript框架

    特点:

    • 组件化:以组件为基础单位组合成用户界面,方便视图的拆分与模块复用,可以更容易做到高内聚低耦合。
    • 声明式:JSX 方式编写,结构上更容易阅读,而且更容易与其他组件代码进行组合
    • 通用性:因为 Virtual DOM, 使得跨平台成为可能,一处代码到处运行。

    缺点:

    • React 官方没有提供一系列的解决方案,把路由,状态管理等交由社区,导致学习成本和选型方面的造成一点的影响。
    • React 在本身编写过程中组件有些优化的功能需要使用者额外自主处理,比如 shouldComponentUpdateuseMemo

    2. React 最新生命周期 ?

    React 16 打算废弃的是哪些生命周期

    • componentWillMount
    • componentWillReceiveProps
    • componentWillUpdate

    新增的生命周期

    • static getDerivedStateFromProps
    • getSnapshotBeforeUpdate

    目前 React 的生命周期分为三个阶段,分别是挂载阶段(Mounting)、更新阶段(Updating)、卸载阶段(Unmounting)

    挂载阶段:

    • constructor: 构造函数,最先被执行,我们通常在构造函数里初始化state对象或者给自定义方法绑定this
    • getDerivedStateFromProps:参数为 (nextProps, prevState)静态方法,无法获取 this, 用来代替 componentWillReceiveProps,返回值作为 state定向更新
    • render: render 方法不会直接渲染 DOM, 它只是把需要渲染的内容返回回来,真实的渲染 DOM 是由 ReactDOM.render 操作的
    • componentDidMount:真实 DOM 已经渲染并挂载到页面上后触发,这里可以操作真实 DOM, 异步请求、数据初始化这样的操作也尽量放在这个生命周期来做

    更新阶段:

    • getDerivedStateFromProps:在父组件状态更新注意:并不是只有 props改变的情况下,自身状态改变也会触发子组件的此方法)以及自身组件更新的时候都会触发。
    • shouldComponentUpdate:参数 (nextProps, nextState),主要用来优化,返回一个布尔值,true表示会触发重新渲染,false表示不会触发重新渲染。默认是 true
    • render:根据上面函数的返回值,是否重新执行
    • getSnapshotBeforeUpdate:参数(prevProps, prevState), 代替 componentWillUpdate,返回值作为 componentDidUpdate 的第三个参数,此生命周期必须与componentDidUpdate搭配使用
    • componentDidUpdate:在组件更新完毕后被触发,经常被用来处理 DOM 操作

    卸载阶段:

    • componentWillUnmount: 当我们的组件被卸载或者销毁了就会调用,我们可以在这个函数里去清除一些定时器,取消网络请求,清理无效的DOM元素等垃圾清理工作

    3. 为何尽量避免使用废弃生命周期?

    • 比如在 componentWillMount 里发起异步请求,以为可以让页面早点显示出来,但异步请求再怎么快也快不过(React 15 下)同步的生命周期。componentWillMount 结束后,render 会迅速地被触发,所以说首次渲染依然会在数据返回之前执行。这样做不仅没有达到你预想的目的,还会导致服务端渲染场景下的冗余请求等额外问题,得不偿失。
    • Fiber 架构下会因为中断和重启导致多次调用,如果内部有付款类的接口请求则会出现大问题
    • 防止各种骚操作,比如在 componentWillReceiveProps 中使用 setState 直接爆栈

    4. React Hook 比起 Class 有什么优缺点?

    • 优点
    1. 解决 classthis 和 生命周期两大痛点
    2. 更好地拆分逻辑代码,每个 Hook 就做一件事
    3. 更好地复用代码,不会跟 HOC 一样出现嵌套地狱
    • 缺点
    1. 缺少 getSnapshotBeforeUpdate 这类生命周期的实现
    2. 在过度复杂或者过度拆分方面摇摆不定,对开发者的水平提出了更高的要求。
    3. Hooks 在使用层面有着严格的规则约束(比如不要在循环、条件或嵌套函数中调用 Hook。)

    5. React Hook 的工作机制

    Hook 数据结构即是一个单向串联的链表

    • 首次渲染,执行 mountState, 创建 hook 对象,存储 initialState, 并把 hook 加到链路最后方
    • 更新,执行 updateState,按顺序去遍历之前构建好的链表,取出对应的数据信息进

    hooks 的渲染是通过 依次遍历 来定位每个 hooks 内容的。如果把Hook 写在 if 语句 里,前后两次读到的链表在顺序上出现差异,那么渲染的结果自然是不可控的。

    6. 什么是 Virtual DOM ?

    Virtual DOM就是 JSDOM 之间的一个映射缓存,说白了就是一个描述 DOMJS对象。

    React 中是通过 Babel 转译 JSX 之后,调用React.createElement 生成的 JS对象。

    7. 为什么需要 Virtual DOM ?

    很多人会说因为直接操作DOM很慢,会导致频繁的回流与重绘。JS 操作Virtual DOM 不会发生这种情况,所以 Virtual DOMDOM快...... 其实这并不是正确的结论。

    选择Virtual DOM,可以在每次更新的时候直接对比 Virtual DOM 的差异,然后只需要更新发生变化的部分即可。但这并不是为了防止频繁的操作DOM带来的不好的性能体验,而是为了让开发者用的,无需去写一堆DOM操作,直接修改数据,让数据驱动视图,它提供了更高效的研发模式,以及一个还不错的性能体验。

    而说 DOMVirtual DOM 快的观点,也是不够严谨的。比如有一串数据非常简单的列表数据, 但又发生了巨大的改变, Virtual DOM在更新时会经过构建新的虚拟DOM树 -> diff 比较 -> 渲染真实 DOM, 这种情况来看,DOM 明显会更快

    Virtual DOM 的价值主要体现在提升研发体验/研发效率以及跨平台的功能上

    8. React Diff 复杂度是 O (n) ?

    Diff 过程中,对比两个 Virtual DOM 树的变化,一般找出两个树结构之间的不同,需要循环递归进行树节点的一一对比,这个过程的算法复杂度是 O (n^3)

    React 团队通过分层对比,即只针对相同层级的节点作对比,如果如果节点是同一类型才会向下比较,否则放弃比较,直接原地替换掉旧的节点。这样的时间复杂度是 O (n)

    9. React key 的作用? 可不可以使用 index 作为 key ?

    key 主要解决的是同一层级的下节点的重用问题。比如对比两个列表数据的变化,key 为每个节点添加了唯一标识,而在 Diff 通过这些标识来判断节点是否销毁,移动,新增。

    如果不写 key 或者使用 index 作为 key, 则标识无法判断唯一性,也就不知道节点是否移动或者销毁,这就会导致在替换过程中直接复用当前节点的内容。这就可能出现节点状态在此过程中出现错误的情况,比如input输入框内数据在更新后还会存在于原来位置的问题。

    10. setState 到底是同步的,还是异步的?

    在通常情况下 setState 是异步的,但在比如 setTimeout 里却是同步的。

    • 异步
    state = {
     count: 0;
    }
    
    this.setState({
      count: this.state.count + 1
    });
    this.setState({
      count: this.state.count + 2
    });
    this.setState({
      count: this.state.count + 3
    });
    
    consle.log(this.state.count); // 结果为 3
    

    打印结果依旧为 0, 而且更新之后,count 会变成 3,而不是1 + 2 + 3 = 6,因为在多次调用setState后,count 并不会累次相加,而是会加入一个任务队列进行合并操作,对于相同属性的设置只会执行最后一次的更新

    • 同步
    state = {
     count: 0;
    }
    
    setTimeout(() => {
      this.setState({
        count: this.state.count + 1
      });
      consle.log(this.state.count); // 结果为 1
    }, 0) 
    

    由于 setTimeout 的宏任务机制,逃出了 React 的异步掌控,在执行的时候, React 内部已经关闭了批量更新的标识.

    11. Stack Reconciler vs Fiber Reconciler

    • Stack Reconciler

    React 15Reconciler机制,由于 JavaScript线程渲染UI线程 互斥,所以如果 React 组件足够复杂,在更新之时会同步递归渲染整个组件树导致 JavaScript线程 一直占用 主线程, 而 渲染UI线程则长时间挂起,就会出现卡顿的效果。

    • Fiber Reconciler

    Fiber 则把一个庞大的更新任务被分解为了一个个的工作单元,每个工作单元有着不同的优先级,通过 Scheduler 来调度这些优先级,如果更新过程中有更高的优先级任务(比如用户输入),则中断当前任务,待渲染完成后继续执行之前的任务(所以存在部分生命周期重复执行的问题)

    结语

    其实很多内容可以结合源码来看,每个点都可以写很长的一篇文章,这里种子做了一个简单的整理,并不能作为面试的回答,因为确实比较浅显。更多的作用是作为学习和复习的引子,先作为理论,之后结合源码深入学习。

    参考文献

    • 深入浅出搞定 React
    • 前端面试宝典之 React 篇
    • 2019年17道高频React面试题及详解

    起源地下载网 » React 面试简单知识点整理

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元