当前位置: 首页 > Web前端 > HTML

滴滴前端高频react面试题总结

时间:2023-03-28 14:35:18 HTML

说说React组件开发中关于scope的常见问题。在EMAScript5语法规范中,关于作用域的常见问题如下。(1)在map等方法的回调函数中,必须绑定this的作用域(通过bind方法)。(2)父组件传递给子组件的方法作用域是父组件的实例化对象,不能改变。(3)组件事件回调函数方法的作用域为组件实例化对象(绑定父组件提供的方法为父组件实例化对象),不可更改。在EMAScript6语法规范中,关于作用域的常见问题如下。(1)当使用箭头函数作为map等方法的回调函数时,箭头函数的作用域为当前组件的实例化对象(即箭头函数的作用域为定义的作用域),并且不需要绑定范围。(2)事件回调函数必须绑定到组件作用域。(3)父组件的传递方法必须绑定父组件的作用域。简而言之,在EMAScript6语法规范中,组件方法的范围是可以改变的。什么是反应纤维?Fiber是React16中新的协调引擎或核心算法的重新实现。它的主要目标是支持虚拟DOM的增量渲染。ReactFiber的目标是提高其在动画、布局、手势、暂停、中止或重用方面的可用性,并为不同类型的更新分配优先级,以及新的并发原语。ReactFiber的目标是增强其在动画、布局和手势等领域的适用性。它的主要特点是增量渲染:将渲染工作分成块并将其分布在多个帧中的能力。为什么浏览器不能读取JSX?浏览器只能处理JavaScript对象,它们无法读取常规JavaScript对象中的JSX。所以为了让浏览器能够读取JSX,首先需要使用像Babel这样的JSX转换器将JSX文件转换成JavaScript对象,然后传递给浏览器。key在react中的作用很简单:key是虚拟DOM中的一种标识,key在更新显示中起着极其重要的作用。复杂:当state中的数据发生变化时,react会根据[newdata]生成[newvirtualDOM],然后react对[newvirtualDOM]和[oldvirtualDOM]进行diff比较。在这个比较过程中,key是调用setState之后发生的事情的关键合并,触发和解:setState函数之后,传入的参数对象将与当前状态合并,然后开始调用进程构建虚拟DOM根据新状态的树。经过reconciliation过程后,react会根据新的state高效构建虚拟DOM树,准备渲染整个UI页面计算新旧树节点的差异,最小化渲染拉倒新的虚拟DOM树,它会计算新老树的节点差异,在差异计算中会根据差异最小化渲染界面并按需更新,其中react可以比较准确的知道哪些位置发生了变化,如何变化它们,这确保了按需更新而不是宣布重新渲染。React最新的生命周期是什么?在React16之后,放弃了三个生命周期(但没有删除)。componentWillMountcomponentWillReceivePropscomponentWillUpdate官方计划在17版本中彻底删除这三个函数,只保留前缀为UNSAVE_的三个函数以实现向后兼容,但对于开发者来说应该尽量避免使用它们,而是用新的生命周期函数代替。目前,React16.8+的生命周期分为三个阶段,分别是挂载阶段、更新阶段和卸载阶段。挂载阶段:constructor:构造函数,先执行,我们一般在构造函数中初始化state对象或者将this绑定到自定义方法;getDerivedStateFromProps:staticgetDerivedStateFromProps(nextProps,prevState),这是一个静态方法,当我们接收到新的属性并想要修改我们的状态时,我们可以使用getDerivedStateFromPropsrender:渲染函数是一个纯函数,只返回需要渲染的和应该渲染的不包含其他业务逻辑。可以返回原生DOM、React组件、Fragment、Portals、字符串和数字、Boolean和null等;componentDidMount:组件加载完成后调用,此时我们可以拿到DOM节点并进行操作,比如canvas、svg、服务器请求、订阅的操作都可以写在这里面,但是记得在componentWillUnmount中取消订阅;updatephase:getDerivedStateFromProps:这个方法可能在update和mount阶段被调用;shouldComponentUpdate:shouldComponentUpdate(nextProps,nextState),有两个参数nextProps和nextState,表示新的属性和变化后的状态,返回一个布尔值,true表示会触发重新渲染,false表示重新渲染不会触发,默认返回true。我们通常使用这个生命周期来优化React程序的性能;render:更新阶段也会触发这个生命周期;getSnapshotBeforeUpdate:getSnapshotBeforeUpdate(prevProps,prevState),这个方法在render之后,componentDidUpdate之前被调用,有两个参数prevProps和prevState,代表之前的属性和之前的状态,这个函数有一个返回值,会传给componentDidUpdate作为第三个参数。如果不想返回值,可以返回null。这个生命周期必须和componentDidUpdate一起使用;componentDidUpdate:componentDidUpdate(prevProps,prevState,snapshot),这个方法在getSnapshotBeforeUpdate方法之后调用,有三个参数prevProps,prevState,snapshot,表示之前的props,之前的状态,snapshot第三个参数是getSnapshotBeforeUpdate返回的,如果是某个DOM元素的状态需要回调函数,所以比较或者计算过程迁移到getSnapshotBeforeUpdate,然后在componentDidUpdate中统一触发回调或者更新状态。卸载阶段:-componentWillUnmount:当我们的组件被卸载或销毁时它会被调用。我们可以使用这个函数来清除一些定时器,取消网络请求,清理无效的DOM元素等垃圾清理任务。总结:componentWillMount:在渲染前执行,用于根组件中App级的配置;componentDidMount:在第一次渲染后执行,可以在这里进行AJAX请求、DOM操作或状态更新,并设置事件监听器;componentWillReceiveProps:在render初始化的时候不会执行。当组件接收到新状态(Props)时,它将被触发。一般用于父组件状态更新时子组件的重新渲染。shouldComponentUpdate:判断是否更新组件。默认情况下它返回true。如果确定更新state或props后组件不需要重新渲染,可以返回false,这是一种提高性能的方法;componentWillUpdate:在shouldComponentUpdate返回true之前执行,判断要更新的组件;componentDidUpdate:主要用于更新DOM以响应props或状态变化;componentWillUnmount:它用于取消任何网络请求,或删除与该组件关联的所有事件侦听器。什么是JSX的详细解答参考前端进阶面试题。jsx是javascriptML的简称,是react使用的文件,它利用了JavaScript的表现力和类似HTML的模板语法,使得HTML文件非常容易理解。该文件可以使应用程序非常可靠并提高其性能。定义虚拟DOM时,定义虚拟DOM时不需要写引号。在jsx中写标签的类名时需要使用{}。当className替换类内联样式时,style={{key:value}}标签必须关闭。如果是小写字母,将jsx转为html中的同名元素。如果html中没有这个标签对应的同名元素就会报错。如果是大写字母,react会渲染对应的组件。如果没有定义组件,会报错。数据遍历生成标签时,必须为标签设置单独的key,否则会报错。ReactNative中adbdevices找不到连接的设备怎么解决?使用Genymotion时,首先需要在SDK的platform-tools中添加环境变量,然后在Genymotion中点击Setting,选择ADB标签,点击UsecustomAndroidSDKtools,浏览本地SDK所在位置,点击OK按钮。好的。启动虚拟机后,在cmd中输入adbdevices查看设备。React性能优化方案重写shouldComponentUpdate,避免不必要的dom操作。使用react.js的生产版本使用keys来帮助React识别列表中所有子组件的最小变化。React如何检查和更改数据?SetState),触发虚拟dom的更新,然后使用diff算法比较虚拟DOM和真实DOM,看更新的是哪个dom节点,然后渲染真实domredux和mobx的区别?两者比较:redux将数据存储在单个store中,mobx将数据存储在多个分散的store中,redux使用plainobject存储数据,需要手动处理变化的操作;mobx适合在observable中存储数据,数据变化后自动处理响应的操作。Redux使用不可变状态,也就是说状态是只读的,不能直接修改。相反,它应该返回一个新状态并同时使用纯函数;mobx中的状态是可变的,可以直接修改。mobx比较简单,里面有很多抽象。Mobx使用了更多面向对象的编程思想;redux会比较复杂,因为不太容易掌握的函数式编程思想,同时需要一系列的中间件来处理异步和副作用。Mobx有更多的抽象和封装,调试会更困难,结果也不可预测;而redux提供了能够及时回溯的开发工具,其纯粹的功能和较少的抽象使得调试更容易场景识别:基于以上差异,我们可以简单分析一下两者不同的使用场景。mobx更适合数据不太复杂的应用:mobx调试难度大,很多状态无法回溯。在面对高复杂度的应用时,往往无法如愿以偿。Redux适合需要回溯的应用:比如画板应用或者表格应用,需要undo、redo等很多操作。由于redux的不可变特性,自然支持这些操作。mobx适用于短、扁平、快速的项目:mobx简单易用,样板代码少,可以大大提高开发效率。当然,mobx和redux并不是非此即彼的关系。您还可以在项目中使用redux作为全局状态管理器,使用mobx作为组件本地状态管理器。你对【单一数据源】的理解是什么redux使用store将程序的整个状态存储在一个地方,因此所有组件的状态都存储在Store中,它们从Store本身接收更新。单个状态树可以更轻松地跟踪随时间的变化,以及调试或检查程序。Reducer文件中,返回结果需要注意哪些问题?在Reducer文件中,对于返回的结果,必须使用Object.assign()复制一个新的状态,否则页面不会随着数据刷新。返回Object.assign({},state,{type:action.type,shouldNotPaint:true,});哪些方法会触发React重新渲染?render又做了什么?(1)哪些方法会触发react重新渲染?setState()方法被调用。setState是React中最常用的命令。通常,执行setState会触发render。但这里有一点值得关注。执行setState时,不一定会重新渲染。当setState传null时,render不会被触发。类App扩展了React。组件{state={a:1};渲染(){控制台。日志(“渲染”);return(

{this.state.a}

{this.setState({a:1});//这里不改变值ofa}}>Clickmethis.setState(null)}>setStatenull);}}父组件重新渲染只要父组件重新渲染,即使传入子组件的props没有改变,那么子组件也会重新渲染,然后触发render(2)会怎样重新渲染渲染呢?它会比较新旧VNodes,也就是我们所说的Diff算法。对新老树进行一次深度优先遍历,这样每个节点都会有一个标记。深度遍历时,每遍历一个结点,将该结点与新的结点树进行比较。如果有差异,则将其放入一个对象中,遍历差异对象,根据差异类型更新VNodeReact处理render,并根据相应的规则更新VNodeReact处理render。基本的思维模式是每次有变化就重新渲染整个应用。在VirtualDOM出现之前,最简单的方式就是直接调用innerHTML。VirtualDOM的伟大之处不在于它比直接操作DOM更快,而在于无论数据如何变化,它都会尝试以最小的代价更新DOM。React将渲染函数返回的虚拟DOM树与旧树进行比较,以确定是否以及如何更新DOM。当DOM树很大时,遍历两棵树进行各种比较是相当耗费性能的,尤其是顶层setState的一个小变化,默认会遍历整棵树。尽管React使用了高度优化的Diff算法,但这个过程仍然会消耗性能。redux的缺点是什么?组件需要的数据必须从父组件传递过来,而不是像influx那样直接从store中更新,即使父组件不需要使用这个组件,父组件还是会重新渲染,可能会影响效率,或者需要写复杂的shouldComponentUpdate来判断对React-Fiber的理解,它解决什么问题?ReactV15在渲染时,会递归比较VirtualDOM树,找出需要更改的节点,然后同步更新,一气呵成。在这个过程中,React会占用浏览器资源,导致用户触发的事件无响应,并导致掉帧,让用户有卡顿的感觉。为了给用户造成应用很快的“假象”,不能让一个任务长时间占用资源。浏览器的渲染、布局、绘制、资源加载(如HTML解析)、事件响应、脚本执行等都可以看作是操作系统的“进程”,需要通过一定的调度策略合理分配CPU资源,以提高浏览器性能。用户响应率,同时兼顾任务执行效率。所以React使用Fiber架构让这个执行过程可以中断。“及时”放弃CPU执行权,不仅可以让浏览器及时响应用户交互,还有其他好处:批量操作DOM并延迟操作,避免操作大量DOM一次结点,获得更好的用户体验;给浏览器一点喘息的空间,它会编译和优化代码(JIT)并进行热代码优化,或纠正回流。核心思想:Fiber也叫coroutine或者fiber。它与线程不同。协程本身没有并发或并行能力(需要和线程配合)。它只是一种放弃控制过程的机制。放弃CPU的执行权,让CPU在这段时间内可以进行其他的操作。渲染过程可以被中断,将控制权交还给浏览器让位于高优先级的任务,并在浏览器空闲后恢复渲染。什么是组件?什么是类?编译成类的组件是指页面的一部分。它本质上是一个类,最本质的是一个构造函数。该类被编译成构造函数。如何避免React中不必要的渲染?基于虚拟DOM与高效Diff算法的完美配合,React实现了DOM最小粒度的更新。在大多数情况下,React对DOM的渲染对于日常业务来说已经足够高效了。但是,在一些复杂的业务场景中,性能问题仍然困扰着我们。这时就需要采取一些措施来提高运行性能。最重要的方向之一是避免不必要的渲染(Render)。这里有一个优化点:shouldComponentUpdate和PureComponent在React类组件中,可以使用shouldComponentUpdate或PureComponent来减少父组件更新触发的子组件渲染,从而达到目的。shouldComponentUpdate用于确定是否应该重新渲染组件。如果您不想重新渲染组件,只需返回false。使用高阶组件在函数组件中,没有shouldComponentUpdate的生命周期。您可以使用高阶组件来封装类似于PureComponet的功能。使用React.memoReact.memo是React16.6中新增的API,用于缓存组件渲染,避免不必要的更新,其实是一个高级组件,和PureComponent很相似,但不同的是React.memo只能使用对于功能组件。当React中的props发生变化时,有哪些方法可以更新组件?当组件传入的props更新时,一种常见的重新渲染组件的方法是在componentWillReceiveProps中将新的props更新为组件的状态(这个状态称为派生状态(DerivedState)),从而实现重新渲染。React16.3还引入了一个新的钩子函数getDerivedStateFromProps来专门实现这个需求。(1)componentWillReceiveProps(deprecated)在react的componentWillReceiveProps(nextProps)生命周期中,在子组件的render函数执行之前,可以通过this.props获取旧的properties,通过nextProps获取新的props。比较两个props是否相同,从而更新子组件自身的状态。这样做的好处是数据请求可以放在这里执行,需要传递的参数从componentWillReceiveProps(nextProps)中获取。而不是把所有的请求都放在父组件中。那么只有在组件渲染时才会发送请求,从而减轻请求负担。(2)getDerivedStateFromProps(16.3引入)是一个生命周期函数,用来替代componentWillReceiveProps,所以当你需要使用componentWillReceiveProps时,可以考虑使用getDerivedStateFromProps代替。两者的参数不同,getDerivedStateFromProps是静态函数,即这个函数不能通过this访问类的属性,不建议直接访问属性。而是应该通过参数提供的nextProps和prevState进行判断,根据新传入的props映射到state。需要注意的是,如果props传入的内容不需要影响你的state,那么你需要返回一个null。这个返回值是必须的,所以尽量写在函数的末尾:staticgetDerivedStateFromProps(nextProps,prevState){const{type}=nextProps;//当传入的类型改变时,更新状态if(type!==prevState.type){return{type,};}//否则,对状态什么也不做returnnull;}什么是状态?组件初始化时,通过this.state为组件设置一个初始状态。当它第一次被渲染时,它会使用状态来渲染组件。使用this.setState方法更新状态