前端面试(React框架二)

简介: 本文对比了React中class与createClass的用法,探讨Vue与React在数据更新、模板语法及优化机制上的差异,解析高阶组件(HOC)的复用逻辑、React事件机制中的合成事件与事件代理,并深入讲解Redux状态管理流程及其纯函数reducer的设计原理。同时介绍虚拟DOM(VDOM)的结构、Diff算法的同层比对与key值作用,说明其如何提升渲染性能,适用于Vue和React的核心更新机制。

17. class和createClass的比较

一个调用React.createClass并传入一个对象,另一个则是使用class继承React.Component

var InputControlES5 = React.createClass({
propTypes: {
  initialValue: React.PropTypes.string
},
defaultProps: {
  initialValue: ''
}, // Set up initial state
getInitialState: function() {
  return {
    text: this.props.initialValue || 'placeholder'
  };
},
handleChange: function(event) {
  this.setState({
    text: event.target.value
  });
},
render: function() {
  return (
    <div>
      Type something:
      <input onChange={this.handleChange}
        value={this.state.text} />
      </div>
    );
  }
});
Copy

18. 谈一下Vue 和 React区别?

  1. 改变数据方式不同,Vue 修改状态相比来说要简单许多,React 需要使用 setState 来改变状态,并且使用这个 API 也有一些坑点。
  2. Vue 的底层使用了依赖追踪,页面更新渲染已经是最优的了,但是 React 还是需要用户手动去优化这方面的问题。
  3. React 需要使用 JSX,Vue 使用了模板语法

19. 高阶组件 HOC (higher order component)

高阶组件是一个以组件为参数并返回一个新组件的函数。

  1. HOC 允许你重用代码、逻辑和引导抽象。
  2. 最常见的可能是 Redux 的 connect 函数。
  3. 除了简单分享工具库和简单的组合,HOC 最好的方式是共享 React 组件之间的行为。
  4. 如果你发现你在不同的地方写了大量代码来做同一件事时,就应该考虑将代码重构为可重用的 HOC。
function add(a, b) {
    return a + b
}
Copy

现在如果我想给这个 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)
Copy

这个做法在函数式编程里称之为高阶函数,大家都知道 React 的思想中是存在函数式编程的,高阶组件和高阶函数就是同一个东西。我们实现一个函数,传入一个组件,然后在函数内部再实现一个函数去扩展传入的组件,最后返回一个新的组件,这就是高阶组件的概念,作用就是为了更好的复用代码。

20. 谈一下React的事件机制

React 其实自己实现了一套事件机制,首先我们考虑一下以下代码

const Test = ({ list, handleClick }) => ({
    list.map((item, index) => (
        <span onClick={handleClick} key={index}>{index}</span>
    ))
})
Copy
  1. 事实当然不是,JSX 上写的事件并没有绑定在对应的真实 DOM 上,而是通过事件代理的方式,将所有的事件都统一绑定在了document。这样的方式不仅减少了内存消耗,还能在组件挂载销毁时统一订阅和移除事件。
  2. 另外冒泡到 document 上的事件也不是原生浏览器事件,而是React自己实现的合成事件(SyntheticEvent)。因此我们如果不想要事件冒泡的话,调用 event.stopPropagation 是无效的,而应该调用 event.preventDefault。
  3. 那么实现合成事件的目的好处有两点,分别是:
  • 合成事件首先抹平了浏览器之间的兼容问题,另外这是一个跨浏览器原生事件包装器,赋予了跨浏览器开发的能力
  • 对于原生浏览器事件来说,浏览器会给监听器创建一个事件对象。如果你有很多的事件监听,那么就需要分配很多的事件对象,造成高额的内存分配问题。但是对于合成事件来说,有一个事件池专门来管理它们的创建和销毁,当事件需要被使用时,就会从池子中复用对象,事件回调结束后,就会销毁事件对象上的属性,从而便于下次复用事件对象。

21. redux简介

redux 是一个应用数据流框架,主要是解决了组件间状态共享的问题,原理是集中式管理,主要有三个核心方法,action,store,reducer

工作流程是:

  • view用actionCreator创建一个action,里面可能包含一些数据
  • 使用store的dispatch方法将acion传入store
  • store将action与旧的state转发给reducer
  • reducer深拷贝state,并返回一个新的state给store
  • store接收并更新state
  • 使用store.subscribe订阅更新,重新render组件

21.1 reducer为什么是纯函数?

Note

从本质上讲,纯函数的定义如下:不修改函数的输入值,依赖于外部状态(比如数据库,DOM和全局变量),同时对于任何相同的输入有着相同的输出结果。

21.2 原理解析

  1. 阅读源码可以看到,Redux接收一个给定的state(对象),然后通过循环将state的每一部分传递给每个对应的reducer。如果有发生任何改变,reducer将返回一个新的对象。如果不发生任何变化,reducer将返回旧的state。
  2. Redux只通过比较新旧两个对象的存储位置来比较新旧两个对象是否相同(也就是Javascript对象浅比较)。如果你在reducer内部直接修改旧的state对象的属性值,那么新的state和旧的state将都指向同一个对象。因此Redux认为没有任何改变,返回的state将为旧的state。
  3. 深比较在真实的应用当中代价昂贵,因为通常js的对象都很大,同时需要比较的次数很多。
  4. 因此一个有效的解决方法是作出一个规定:无论何时发生变化时,开发者都要创建一个新的对象,然后将新对象传递出去。同时,当没有任何变化发生时,开发者发送回旧的对象。也就是说,新的对象代表新的state。 使用了新的策略之后,你能够比较两个对象通过使用!==比较两个对象的存储位置而不是比较两个对象的所有属性。

22. VDOM是什么?为什么会存在VDOM?

22.1 VDom的产生原因

  1. 非常耗费性能的。而且JS操作DOM是非常复杂,JS操作DOM越多,控制与页面的耦合度就越高,代码越难以维护。
  2. 虚拟DOM,即用JS对象来描述DOM树结构,Diff算法则是找旧VDOM与新的VDOM的最小差异,然后再把差异渲染出来

22.2 VDOM的组成

  • tag 标签名
  • attrs DOM属性键值对
  • childen DOM字节点数组 或 文本内容

如何理解虚拟 DOM?-zhihu

22.3 为什么DOM操作慢? 因为属性太多了

22.4 vdom如何应用,核心API是什么?

  1. 创建虚拟节点
  • h('标签名', {...属性...}, [...子元素...])
  • h('标签名', {...属性...}, '文本内容')
  1. 将VNode添加到一个DOM元素内
  • patch(DOM_obj, vnode);
  1. 用一个新的vnode来和旧的vnode进行比较,得出新旧dom的差异
  2. patch(vnode, newVnode)

23. diff算法

23.1 对比Vdom树差异的算法

React 的 diff 算法

23.2 同层比对

新旧状态的比对时采用同层比对,当发现某节点不一致了直接替换该节点的子树。而不管它的子树是不是真的改动了。

23.3 key值的使用

  1. 在列表循环的时候React会要求每一个列表项有一个独一无二稳定的key值,它的目的是为了当状态改变时新旧状态的每一个列表项能够对应起来,方便比对。
  2. Key 是 React 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识。
  3. Diff 算法中 React 会借助元素的 Key 值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染。此外,React 还需要借助 Key 值来判断元素与本地状态的关联关系

23.4 合并操作

调用 component 的 setState 方法的时候, React 将其标记为 dirty.到每一个事件循环结束, React 检查所有标记 dirty 的 component 重新绘制

23.5 diff算法的流程

  1. tree diff 新旧两棵DOM树,逐层对比的过程,就是 Tree Diff; 当整颗DOM逐层对比完毕,则所有需要被按需更新的元素,必然能够找到;
  2. component diff 在进行Tree Diff的时候,每一层中,组件级别的对比,叫做 Component Diff;
  • 如果对比前后,组件的类型相同,则暂时认为此组件不需要被更新;
  • 如果对比前后,组件类型不同,则需要移除旧组件,创建新组件,并追加到页面上;(重新创建并追加到页面上去)
  1. element diff 在进行组件对比的时候,如果两个组件类型相同,则需要进行 元素级别的对比,这叫做 Element Diff;

24. Vue和React中key的作用?(面试重点)

  1. 两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构。
  2. 同一层级的一组节点,他们可以通过唯一的id进行区分。

基于以上这两点假设,使得虚拟DOM的Diff算法的复杂度从O(n^3)降到了O(n)。

  1. 当页面的数据发生变化时,Diff算法只会比较同一层级的节点:
  2. 如果节点类型不同,直接干掉前面的节点,再创建并插入新的节点,不会再比较这个节点以后的子节点了。
  3. 如果节点类型相同,则会重新设置该节点的属性,从而实现节点的更新。
  4. 当某一层有很多相同的节点时,也就是列表节点时,Diff算法的更新过程默认情况下也是遵循以上原则。

Note

所以一句话,key的作用主要是为了高效的更新虚拟DOM。另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。

目录
相关文章
|
2月前
|
运维 JavaScript 前端开发
Teek Design Vue3 Element Plus 中后台系统开发模板
Teek Design Vue3 是基于 Vue3 + TypeScript + Vite + Element Plus 的中后台系统开发模板,支持多布局、RBAC权限、主题切换与丰富组件,集成 ECharts、富文本等常用能力,开箱即用,适合企业后台、数据看板等场景。MIT 开源协议,配备完整工程化规范与多环境部署方案。
314 2
Teek Design Vue3 Element Plus 中后台系统开发模板
|
2月前
|
人工智能 前端开发 Docker
Huobao Drama 开源短剧生成平台:从剧本到视频
Huobao Drama 是一个基于 Go + Vue3 的开源 AI 短剧自动化生成平台,支持剧本解析、角色与分镜生成、图生视频及剪辑合成,覆盖短剧生产全链路。内置角色管理、分镜设计、视频合成、任务追踪等功能,支持本地部署与多模型接入(如 OpenAI、Ollama、火山等),搭配 FFmpeg 实现高效视频处理,适用于短剧工作流验证与自建 AI 创作后台。
3279 6
|
2月前
|
前端开发 JavaScript 算法
前端面试(React框架一)
React 是一个用于构建用户界面的 JavaScript 库,采用虚拟 DOM 提升渲染效率,支持组件化开发与服务端渲染,具有良好的性能优化机制和丰富的生命周期管理。
114 13
|
2月前
|
人工智能 Java API
阿里 Assistant Agent 开源,助力开发者快速构建答疑、诊断智能助手
Assistant Agent 是一个基于 Spring AI Alibaba 构建的企业级智能助手框架,采用代码即行动(Code-as-Action)范式,通过生成和执行代码来编排工具、完成任务。它是一个能理解、能行动、能学习的智能助手解决方案,可帮助企业快速构建智能答疑客服、系统诊断、运维助手、业务助理、AIOps 等智能体。
阿里 Assistant Agent 开源,助力开发者快速构建答疑、诊断智能助手
|
2月前
|
人工智能 自然语言处理 前端开发
建造者还是饲料投喂者?AI Agent搭建师职业焦虑与“工具反噬”的幽灵
当AI Agent自主迭代,程序员正面临“工具反噬”的焦虑:我们是智能体的建筑师,还是数据饲养员?本文剖析职业危机根源,揭示从编码者到“人机指挥家”的进化之路,探寻人类在智能洪流中不可替代的价值锚点——意图、判断与创造力。
100 3
|
2月前
|
前端开发 JavaScript Java
前端面试题(ES6框架)
本文深入讲解ES6核心知识,涵盖Webpack环境搭建、模块化演进、class与构造函数对比、Promise原理实现及Proxy、箭头函数等新特性,结合代码示例解析,助力掌握现代JavaScript开发要点.
75 1
|
2月前
|
开发者
Mac Axure RP 9.dmg 安装教程 简单步骤 含汉化方法
Axure RP 9 是专为原型设计打造的工具,适用于绘制网页与APP交互稿,支持无代码预览产品效果。本文介绍其在Mac上的下载、安装、授权及中文汉化步骤,助你快速上手使用。(238字)
|
2月前
|
弹性计算 人工智能 大数据
阿里云服务器是做什么的?ECS介绍及租赁配置价格整理,一文看懂~
阿里云ECS是IaaS级弹性计算服务,提供虚拟服务器,支持按需租赁、弹性扩缩容,适用于网站搭建、应用部署、大数据处理等场景,具备高可用、成本可控等优势,助力个人与企业高效上云。
856 1

热门文章

最新文章