百度前端必会react面试题总结

news/2024/3/29 8:35:52/文章来源:https://blog.csdn.net/beifeng11996/article/details/129120417

对 React 和 Vue 的理解,它们的异同

相似之处:

  • 都将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库
  • 都有自己的构建工具,能让你得到一个根据最佳实践设置的项目模板。
  • 都使用了Virtual DOM(虚拟DOM)提高重绘性能
  • 都有props的概念,允许组件间的数据传递
  • 都鼓励组件化应用,将应用分拆成一个个功能明确的模块,提高复用性

不同之处:

1)数据流

Vue默认支持数据双向绑定,而React一直提倡单向数据流

2)虚拟DOM

Vue2.x开始引入"Virtual DOM",消除了和React在这方面的差异,但是在具体的细节还是有各自的特点。

  • Vue宣称可以更快地计算出Virtual DOM的差异,这是由于它在渲染过程中,会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。
  • 对于React而言,每当应用的状态被改变时,全部子组件都会重新渲染。当然,这可以通过 PureComponent/shouldComponentUpdate这个生命周期方法来进行控制,但Vue将此视为默认的优化。

3)组件化

React与Vue最大的不同是模板的编写。

  • Vue鼓励写近似常规HTML的模板。写起来很接近标准 HTML元素,只是多了一些属性。
  • React推荐你所有的模板通用JavaScript的语法扩展——JSX书写。

具体来讲:React中render函数是支持闭包特性的,所以我们import的组件在render中可以直接调用。但是在Vue中,由于模板中使用的数据都必须挂在 this 上进行一次中转,所以 import 完组件之后,还需要在 components 中再声明下。

4)监听数据变化的实现原理不同

  • Vue 通过 getter/setter 以及一些函数的劫持,能精确知道数据变化,不需要特别的优化就能达到很好的性能
  • React 默认是通过比较引用的方式进行的,如果不优化(PureComponent/shouldComponentUpdate)可能导致大量不必要的vDOM的重新渲染。这是因为 Vue 使用的是可变数据,而React更强调数据的不可变。

5)高阶组件

react可以通过高阶组件(Higher Order Components-- HOC)来扩展,而vue需要通过mixins来扩展。

原因高阶组件就是高阶函数,而React的组件本身就是纯粹的函数,所以高阶函数对React来说易如反掌。相反Vue.js使用HTML模板创建视图组件,这时模板无法有效的编译,因此Vue不采用HOC来实现。

6)构建工具

两者都有自己的构建工具

  • React ==> Create React APP
  • Vue ==> vue-cli

7)跨平台

  • React ==> React Native
  • Vue ==> Weex

生命周期调用方法的顺序是什么?

React生命周期分为三大周期,11个阶段,生命周期方法调用顺序分别如下。
(1)在创建期的五大阶段,调用方法的顺序如下。

  • getDetaultProps:定义默认属性数据。

  • getInitialState:初始化默认状态数据。

  • component WillMount:组件即将被构建。

  • render:渲染组件。

  • componentDidMount:组件构建完成

(2)在存在期的五大阶段,调用方法的顺序如下。

  • componentWillReceiveProps:组件即将接收新的属性数据。

  • shouldComponentUpdate:判断组件是否应该更新。

  • componnent WillUpdate:组件即将更新。

  • render:渲染组件。

  • componentDidUpdate:组件更新完成。

(3)在销毁期的一个阶段,调用方法 componentWillUnmount,表示组件即将被销毀。

React 如何区分 Class组件 和 Function组件

一般的方式是借助 typeof 和 Function.prototype.toString 来判断当前是不是 class,如下:

function isClass(func) {return typeof func === 'function'&& /^class\s/.test(Function.prototype.toString.call(func));
}

但是这个方式有它的局限性,因为如果用了 babel 等转换工具,将 class 写法全部转为 function 写法,上面的判断就会失效。

React 区分 Class组件 和 Function组件的方式很巧妙,由于所有的类组件都要继承 React.Component,所以只要判断原型链上是否有 React.Component 就可以了:

AComponent.prototype instanceof React.Component

React的Fiber工作原理,解决了什么问题

  • React Fiber 是一种基于浏览器的单线程调度算法。

React Fiber 用类似 requestIdleCallback 的机制来做异步 diff。但是之前数据结构不支持这样的实现异步 diff,于是 React 实现了一个类似链表的数据结构,将原来的 递归diff 变成了现在的 遍历diff,这样就能做到异步可更新了

refs的作用是什么,你在什么样的业务场景下使用refs

  • 操作DOM,为什么操作DOM?
  • 场景
    • 图片渲染好后,操作图片宽高。比如做个放大镜功能

constructor 为什么不先渲染?

由ES6的继承规则得知,不管子类写不写constructor,在new实例的过程都会给补上constructor。

所以:constructor钩子函数并不是不可缺少的,子组件可以在一些情况略去。比如不自己的state,从props中获取的情况

参考 前端进阶面试题详细解答

调用 setState 之后发生了什么

在代码中调用 setState 函数之后,React 会将传入的参数与之前的状态进行合并,然后触发所谓的调和过程(Reconciliation)。经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面。在 React 得到元素树之后,React 会计算出新的树和老的树之间的差异,然后根据差异对界面进行最小化重新渲染。通过 diff 算法,React 能够精确制导哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。

  • 在 setState 的时候,React 会为当前节点创建一个 updateQueue 的更新列队。
  • 然后会触发 reconciliation 过程,在这个过程中,会使用名为 Fiber 的调度算法,开始生成新的 Fiber 树, Fiber 算法的最大特点是可以做到异步可中断的执行。
  • 然后 React Scheduler 会根据优先级高低,先执行优先级高的节点,具体是执行 doWork 方法。
  • 在 doWork 方法中,React 会执行一遍 updateQueue 中的方法,以获得新的节点。然后对比新旧节点,为老节点打上 更新、插入、替换 等 Tag。
  • 当前节点 doWork 完成后,会执行 performUnitOfWork 方法获得新节点,然后再重复上面的过程。
  • 当所有节点都 doWork 完成后,会触发 commitRoot 方法,React 进入 commit 阶段。
  • 在 commit 阶段中,React 会根据前面为各个节点打的 Tag,一次性更新整个 dom 元素

简述react事件机制

当用户在为onClick添加函数时,React并没有将Click时间绑定在DOM上面
而是在document处监听所有支持的事件,当事件发生并冒泡至document处时,React将事件内容封装交给中间层SyntheticEvent(负责所有事件合成)
所以当事件触发的时候,对使用统一的分发函数dispatchEvent将指定函数执行。React在自己的合成事件中重写了 stopPropagation方法,将 isPropagationStopped设置为 true,然后在遍历每一级事件的过程中根据此遍历判断是否继续执行。这就是 React自己实现的冒泡机制

redux 有什么缺点

  • 一个组件所需要的数据,必须由父组件传过来,而不能像 flux 中直接从 store 取
  • 当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新 render,可能会有效率影响,或者需要写复杂的 shouldComponentUpdate 进行判断

高阶组件的应用场景

权限控制

利用高阶组件的 条件渲染 特性可以对页面进行权限控制,权限控制一般分为两个维度:页面级别 和 页面元素级别

// HOC.js    
function withAdminAuth(WrappedComponent) {    return class extends React.Component {    state = {    isAdmin: false,    }    async componentWillMount() {    const currentRole = await getCurrentUserRole();    this.setState({    isAdmin: currentRole === 'Admin',    });    }    render() {    if (this.state.isAdmin) {    return <WrappedComponent {...this.props} />;    } else {    return (<div>您没有权限查看该页面,请联系管理员!</div>);    }    }    };    
}// 使用
// pages/page-a.js    
class PageA extends React.Component {    constructor(props) {    super(props);    // something here...    }    componentWillMount() {    // fetching data    }    render() {    // render page with data    }    
}    
export default withAdminAuth(PageA);    

可能你已经发现了,高阶组件其实就是装饰器模式在 React 中的实现:通过给函数传入一个组件(函数或类)后在函数内部对该组件(函数或类)进行功能的增强(不修改传入参数的前提下),最后返回这个组件(函数或类),即允许向一个现有的组件添加新的功能,同时又不去修改该组件,属于 包装模式(Wrapper Pattern) 的一种。

什么是装饰者模式:在不改变对象自身的前提下在程序运行期间动态的给对象添加一些额外的属性或行为

可以提高代码的复用性和灵活性

再对高阶组件进行一个小小的总结:

  • 高阶组件 不是组件 一个把某个组件转换成另一个组件的 函数
  • 高阶组件的主要作用是 代码复用
  • 高阶组件是 装饰器模式在 React 中的实现

封装组件的原则

封装原则

1、单一原则:负责单一的页面渲染

2、多重职责:负责多重职责,获取数据,复用逻辑,页面渲染等

3、明确接受参数:必选,非必选,参数尽量设置以_开头,避免变量重复

4、可扩展:需求变动能够及时调整,不影响之前代码

5、代码逻辑清晰

6、封装的组件必须具有高性能,低耦合的特性

7、组件具有单一职责:封装业务组件或者基础组件,如果不能给这个组件起一个有意义的名字,证明这个组件承担的职责可能不够单一,需要继续抽组件,直到它可以是一个独立的组件即可

React key 是干嘛用的 为什么要加?key 主要是解决哪一类问题的

Keys 是 React 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识。在开发过程中,我们需要保证某个元素的 key 在其同级元素中具有唯一性。

在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染此外,React 还需要借助 Key 值来判断元素与本地状态的关联关系。

注意事项:

  • key值一定要和具体的元素—一对应;
  • 尽量不要用数组的index去作为key;
  • 不要在render的时候用随机数或者其他操作给元素加上不稳定的key,这样造成的性能开销比不加key的情况下更糟糕。

React 中 keys 的作用是什么?

KeysReact 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识

  • 在开发过程中,我们需要保证某个元素的 key 在其同级元素中具有唯一性。在 React Diff 算法中React 会借助元素的 Key 值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染。此外,React 还需要借助 Key 值来判断元素与本地状态的关联关系,因此我们绝不可忽视转换函数中 Key 的重要性

我现在有一个button,要用react在上面绑定点击事件,要怎么做?

class Demo {render() {return <button onClick={(e) => {alert('我点击了按钮')}}>按钮</button>}
}

你觉得你这样设置点击事件会有什么问题吗?

由于onClick使用的是匿名函数,所有每次重渲染的时候,会把该onClick当做一个新的prop来处理,会将内部缓存的onClick事件进行重新赋值,所以相对直接使用函数来说,可能有一点的性能下降

修改

class Demo {onClick = (e) => {alert('我点击了按钮')}render() {return <button onClick={this.onClick}>按钮</button>}

类组件(Class component)和函数式组件(Functional component)之间有何不同

  • 类组件不仅允许你使用更多额外的功能,如组件自身的状态和生命周期钩子,也能使组件直接访问 store 并维持状态
  • 当组件仅是接收 props,并将组件自身渲染到页面时,该组件就是一个 ‘无状态组件(stateless component)’,可以使用一个纯函数来创建这样的组件。这种组件也被称为哑组件(dumb components)或展示组件

什么原因会促使你脱离 create-react-app 的依赖

当你想去配置 webpack 或 babel presets。

对虚拟 DOM 的理解?虚拟 DOM 主要做了什么?虚拟 DOM 本身是什么?

从本质上来说,Virtual Dom是一个JavaScript对象,通过对象的方式来表示DOM结构。将页面的状态抽象为JS对象的形式,配合不同的渲染工具,使跨平台渲染成为可能。通过事务处理机制,将多次DOM修改的结果一次性的更新到页面上,从而有效的减少页面渲染的次数,减少修改DOM的重绘重排次数,提高渲染性能。

虚拟DOM是对DOM的抽象,这个对象是更加轻量级的对DOM的描述。它设计的最初目的,就是更好的跨平台,比如node.js就没有DOM,如果想实现SSR,那么一个方式就是借助虚拟dom,因为虚拟dom本身是js对象。 在代码渲染到页面之前,vue或者react会把代码转换成一个对象(虚拟DOM)。以对象的形式来描述真实dom结构,最终渲染到页面。在每次数据发生变化前,虚拟dom都会缓存一份,变化之时,现在的虚拟dom会与缓存的虚拟dom进行比较。在vue或者react内部封装了diff算法,通过这个算法来进行比较,渲染时修改改变的变化,原先没有发生改变的通过原先的数据进行渲染。

另外现代前端框架的一个基本要求就是无须手动操作DOM,一方面是因为手动操作DOM无法保证程序性能,多人协作的项目中如果review不严格,可能会有开发者写出性能较低的代码,另一方面更重要的是省略手动DOM操作可以大大提高开发效率。

为什么要用 Virtual DOM:

(1)保证性能下限,在不进行手动优化的情况下,提供过得去的性能

下面对比一下修改DOM时真实DOM操作和Virtual DOM的过程,来看一下它们重排重绘的性能消耗∶

  • 真实DOM∶ 生成HTML字符串+ 重建所有的DOM元素
  • Virtual DOM∶ 生成vNode+ DOMDiff+必要的DOM更新

Virtual DOM的更新DOM的准备工作耗费更多的时间,也就是JS层面,相比于更多的DOM操作它的消费是极其便宜的。尤雨溪在社区论坛中说道∶ 框架给你的保证是,你不需要手动优化的情况下,我依然可以给你提供过得去的性能。 (2)跨平台 Virtual DOM本质上是JavaScript的对象,它可以很方便的跨平台操作,比如服务端渲染、uniapp等。

这段代码有什么问题?

class App extends Component {constructor(props) {super(props);this.state = {username: "有课前端网",msg: " ",};}render() {return <div> {this.state.msg}</div>;}componentDidMount() {this.setState((oldState, props) => {return {msg: oldState.username + " - " + props.intro,};});}
}

render ( < App intro=" 前端技术专业学习平台">,ickt )
在页面中正常输出“有课前端网-前端技术专业学习平台”。但是这种写法很少使用,并不是常用的写法。React允许对 setState方法传递一个函数,它接收到先前的状态和属性数据并返回一个需要修改的状态对象,正如我们在上面所做的那样。它不但没有问题,而且如果根据以前的状态( state)以及属性来修改当前状态,推荐使用这种写法。

何为 reducer

一个 reducer 是一个纯函数,该函数以先前的 state 和一个 action 作为参数,并返回下一个 state。

(组件的)状态(state)和属性(props)之间有何不同

State 是一种数据结构,用于组件挂载时所需数据的默认值。State 可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果。

Props(properties 的简写)则是组件的配置。props 由父组件传递给子组件,并且就子组件而言,props 是不可变的(immutable)。组件不能改变自身的 props,但是可以把其子组件的 props 放在一起(统一管理)。Props 也不仅仅是数据–回调函数也可以通过 props 传递。

redux是如何更新值得

用户发起操作之后,dispatch发送action ,根据type,触发对于的reducer,reducer 就是一个纯函数,接收旧的 state 和 action,返回新的 state。通过 subscribe(listener)监听器,派发更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_71840.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java-路径总和

每日一题 Java-路径总和 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。…

Pyspark基础入门4_RDD转换算子

Pyspark 注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kafka Hbase Hi…

Head First设计模式---2.观察者模式

观察者&#xff08;Observer&#xff09;模式&#xff0c;是一种行为型设计模式&#xff0c;允许你定义一种订阅机制&#xff0c;可以在对象事件发生时通知更多个“观察”该对象的其他对象&#xff0c;类似于“订阅—通知” 问题 假如你有两种类型的对象&#xff0c;顾客和商…

将默认安装的 WSL2 迁移至指定目录

将默认安装的 WSL2 迁移至指定目录WSL2 默认安装在 C 盘下&#xff0c;系统盘空间有限&#xff0c;推荐更改安装目录。 1. 默认安装的 WSL2 目录 C:\Users\cheng\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu20.04onWindows_79rhkp1fndgsc\LocalState\ext4.vhdx 2. …

运筹系列65:TSP问题的精确求解法概述

1. 给定upbound的Christofides方法 这是可以给出上界的一个方法&#xff0c;可以证明构造出的路线不超过最优路线的1.5倍。步骤为&#xff1a; 1&#xff09;构造MST&#xff08;最小生成树&#xff09; 2&#xff09;将里面的奇点连接起来构成欧拉回路称为完美匹配。Edmonds给…

Docker--------Day2

1.Docker镜像 1.1 是什么 镜像 是一种轻量级、可执行的独立软件包&#xff0c;它包含运行某个软件所需的所有内容&#xff0c;我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等)&#xff0c;这个打包好的运行环境就是…

盘点2023年大企业都在用的优秀项目管理软件

行内有句话&#xff1a;每个成功的项目背后肯定有一个成功的项目经理&#xff0c;而每个项目经理背后都少不了一些专业的项目管理工具。要在任何项目中取得成功&#xff0c;对项目进行全面的管理非常关键&#xff0c;包括项目的执行、计划、推进、监控、结果等&#xff0c;有了…

[架构之路-114]-《软考-系统架构设计师》-软件架构设计-7-软件架构评估

前言第7节 软件架构评估7.1 什么是架构评估/为什么要软件架构评估在软硬件系统总体架构设计完成之后&#xff0c;为保证架构设计的合理性、完整性和针对性&#xff0c;从根本上保证系统质量&#xff0c;降低成本及投资风险&#xff0c;需要对总体架构进行评估。7.2 软件架构评估…

rk3568网口CAN串口通信速率性能

通信接口性能参数外设接口性能参数测试结果为实验室实测值&#xff0c;可作为设计参考&#xff0c;但因测试环境和器件批次差异&#xff0c;可能会存在一定的误差&#xff0c;且测试结果依赖评估板性能&#xff0c;核心板搭配不同底板性能也可能存在差异&#xff0c;请结合实际…

OpenEuler安装软件方法

在树莓派上烧录好OpenEuler后上面是什么软件都没有的&#xff0c;像一些gcc的环境都需要自己进行配置。官方提供的安装命令是yum&#xff0c;但是执行yum是找不到命令的&#xff1a;   这个其实是因为OpenEuler中默认的安装软件使用了dnf而不是yum&#xff0c;所以软件的安装…

《Python机器学习》安装anaconda + numpy使用示例

&#x1f442; 小宇&#xff08;治愈版&#xff09; - 刘大拿 - 单曲 - 网易云音乐 目录 一&#xff0c;安装 二&#xff0c;Numpy使用示例 &#xff08;一&#xff09;Numpy数组的创建和访问 1&#xff0c;创建和访问Numpy的一维数组和二维数组 2&#xff0c;Numpy数组…

可调恒流驱动LED电路分析

https://www.icxbk.com/article/detail?aid884 常规使用的pwm调亮度不仅会导致频闪&#xff0c;而且在长时间使用的时候&#xff0c;有损坏led的风险&#xff0c;所以这次设计了一个恒流调亮度电路&#xff0c;其电路图如下所示 电路原理的解读&#xff1a; 左侧的电位计起着…

Eclipse各版本安装Tomcat插件全攻略

Eclipse Tomcat 插件的作用 Eclipse Tomcat 插件可以将Tomcat 集成到Eclipse中&#xff0c;插件安装之后在Eclipse中可以看到类似下面的几个图标&#xff1a; Eclipse Tomcat 插件的主要作用有&#xff1a; 在Eclipse 中可以直接启动&#xff0c;关闭和重启本机的Tomcat可以…

电容的参数-详细描述

贴片电容 如同如所示&#xff0c;MLCC&#xff08;Multi-layer Ceramic Capacitors&#xff09;&#xff0c;外形很好区分。 实际内部结构 使用的还是平行板电容器原理&#xff0c;只是这个是叠层结构&#xff1b;电解电容是卷起来的圆柱状&#xff1b; 容值&#xff1a; …

Ubuntu22.04设置独显用于深度学习运算,核显用于屏幕显示

目录摘要主板bios设置第一步&#xff1a;切换prime-select第二步&#xff1a;关机重启&#xff0c;并将显示器接口插到主板上第三步&#xff1a;设置PRIME Profiles为NVIDIA On-Demand模式注意事项参考文献摘要 目前有需求配置台式机win11Ubuntu的双系统&#xff0c;安装双系统…

linux线程的基本知识

这里用的是Linux的pthread线程库&#xff0c;需要加pthread线程库。 线程的创建 第一个参数是线程id的地址。第二个参数是线程属性&#xff0c;一般为NULL。第三个是要执行的函数。第四个是函数的参数&#xff0c;一般也为NULL 线程的等待&#xff0c;第一个参数是线程的id,第…

SpringBoot之DEBUG远程调试黑科技?

所谓的远程调试就是服务端程序运行在一台远程服务器上&#xff0c;我们可以在本地服务端的代码&#xff08;前提是本地 的代码必须和远程服务器运行的代码一致&#xff09;中设置断点&#xff0c;每当有请求到远程服务器时时能够在本地知道 远程服务端的此时的内部状态。 简单的…

10.现代循环神经网络

10.现代循环神经网络 目录 门控循环单元&#xff08;GRU&#xff09;门控隐状态 重置门和更新门候选隐状态 隐状态从零开始实现 初始化模型参数定义模型训练与预测 简洁实现总结 长短期记忆网络&#xff08;LSTM&#xff09; 门控记忆元 输入门、忘记门和输出门候选记忆元记忆…

论文复现:模拟风电不确定性——拉丁超立方抽样生成及缩减场景(Matlab)

风电出力的不确定性主要源于预测误差&#xff0c;而研究表明预测误差&#xff08;e&#xff09;服从正态分布且大概为预测出力的10%。本代码采用拉丁超立方抽样实现场景生成[1,2]、基于概率距离的快速前代消除法实现场景缩减[3]&#xff0c;以此模拟了风电出力的不确定性。 1 …

蓝桥杯刷题025——推导部分和(加权并查集)

2022省赛 问题描述 对于一个长度为 N 的整数数列 ​, 小蓝想知道下标 l 到 r 的部 分和是多少? 然而, 小蓝并不知道数列中每个数的值是多少, 他只知道它的 M 个部分和 的值。其中第 i 个部分和是下标 ​ 到 的部分和 , 值是 。 输入格式 第一行包含 3 个整数 N、M 和 Q 。分…