React 大厂高频面试题及详细答案(实战向)_第1页
React 大厂高频面试题及详细答案(实战向)_第2页
React 大厂高频面试题及详细答案(实战向)_第3页
React 大厂高频面试题及详细答案(实战向)_第4页
React 大厂高频面试题及详细答案(实战向)_第5页
已阅读5页,还剩2页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

React大厂高频面试题及详细答案(实战向)一、React基础核心面试题1.说说React中虚拟DOM的原理,以及为什么比真实DOM快?虚拟DOM本质就是一个用JS对象描述的真实DOM结构,包含节点类型、属性、子节点等信息。React不会每次数据变化都直接操作真实DOM,而是先在内存中对比新旧两份虚拟DOM的差异,这个过程叫Diff算法,只把差异部分更新到真实DOM。之所以比直接操作真实DOM快,核心原因不是虚拟DOM计算更快,而是减少了频繁、大批量的真实DOM操作。真实DOM自带大量属性和监听,创建、修改、重排重绘成本极高;而JS对象的对比、创建成本极低。同时React会批量更新状态,合并多次修改,进一步减少DOM操作次数。2.React状态更新是同步还是异步?详细说明场景类组件和函数组件的setState/setX状态更新,在合成事件、生命周期中是异步批量更新;在原生事件、定时器、Promise宏微任务中是同步更新。核心原理:React会维护一个更新队列,在自身可控的合成事件流程中,会收集所有状态修改,统一批量执行,避免多次渲染造成性能浪费。脱离React事件管控的场景,无法批量合并,会立即更新。举个实战例子:点击事件里连续两次setState,页面只会渲染一次;setTimeout里两次setState,会渲染两次,且能立刻拿到最新状态。补充:React18之后,所有批量更新都会被统一处理,部分异步场景行为做了归一化,优先批量更新。3.受控组件和非受控组件的区别,项目中怎么选择使用?受控组件:表单值完全由React状态控制,value绑定state,输入变化通过onChange更新state,视图完全受控于数据。优势是数据统一管理、可校验、可联动,适合大部分表单场景。非受控组件:表单值由DOM自身管理,通过ref获取DOM节点值,state不实时绑定表单值。优势是代码简单、开销小,无需维护多余状态。项目选型原则:需要表单校验、联动、禁用、动态修改默认值、数据回显的场景,一律用受控组件;简单一次性输入、无需复杂控制的场景,比如简单搜索框、一次性备注输入,用非受控组件更简洁。4.key的作用是什么?为什么不建议用index做key?key是React列表Diff时节点的唯一标识,作用是让Diff算法精准识别新旧列表中的对应节点,避免错误复用DOM,提升更新效率。不建议用index的核心原因:会引发DOM复用错乱、状态污染。当列表进行删除、插入、排序操作时,数组index会重新分配。原本index对应的节点内容变了,但index没变,React会认为节点没变化,复用旧DOM和内部状态,导致出现输入框内容错乱、组件状态残留、视图渲染错误等问题。最优方案:用后端返回的唯一ID、业务唯一标识作为key。二、ReactHooks高频面试题(核心重点)1.讲讲Hooks的使用规则,为什么必须遵守?两条核心规则:第一,只在函数组件顶层调用Hooks,不能在循环、条件、嵌套函数中调用;第二,只在函数组件和自定义Hooks中调用Hooks,类组件中不能使用。原因:React是靠调用顺序来匹配每一次渲染的Hook状态的。如果在条件、循环中使用,每次渲染Hook执行数量、顺序不一致,会导致状态匹配错乱,出现数据异常、报错。2.useState、useEffect底层原理是什么?React内部维护了一个单向链表,每次函数组件渲染时,会按顺序收集所有Hook。每个Hook对应一个链表节点,存储state值、更新函数、依赖项等信息。useState:首次渲染创建链表节点,存储初始值;更新时修改节点状态,触发组件重渲染,下次渲染从链表读取最新状态。useEffect:渲染完成后,对比新旧依赖项,依赖变化则执行副作用;下次执行前先清理上一次副作用。依赖为空则只执行一次,依赖不变则跳过执行。3.useEffect和useLayoutEffect的区别、使用场景useEffect:在浏览器渲染完成、绘制完毕后执行,不会阻塞页面渲染,是异步执行。适合数据请求、事件监听、定时器、页面订阅等绝大多数副作用场景。useLayoutEffect:在DOM生成后、页面绘制之前同步执行,会阻塞渲染。适合需要操作DOM、读取DOM布局、修改元素样式、避免页面闪烁的场景。实战总结:日常开发优先用useEffect,只有出现布局抖动、闪屏问题时,才替换为useLayoutEffect。4.useCallback、useMemo的作用和区别,解决什么问题?两者都是React缓存工具,用于减少不必要的计算和子组件重渲染,优化性能。useMemo:缓存计算结果,用于缓存复杂计算值,避免每次渲染重复计算。执行时机是渲染阶段,返回一个值。依赖不变时,直接复用上次计算结果。适用于过滤、排序、数据格式化等耗时计算。useCallback:缓存函数本身,避免每次渲染生成新函数引用。主要配合memo实现子组件精准更新,防止父组件渲染导致子组件无辜重渲染。核心区别:useMemo缓存值,useCallback缓存函数;useMemo处理计算性能,useCallback处理组件渲染性能。补充误区:不要所有值和函数都缓存,缓存本身有开销,简单计算、简单函数无需使用。5.自定义Hook的意义,和普通函数的区别自定义Hook本质是封装了内置Hook的函数,核心作用是复用组件逻辑,剥离重复业务,让组件只负责视图渲染,逻辑统一抽离。和普通工具函数的区别:普通函数只能处理纯逻辑、纯计算;自定义Hook可以使用useState、useEffect等React钩子,能拥有组件状态和副作用能力,可以实现数据请求、监听、防抖节流、表单封装等带状态的逻辑复用。三、React进阶原理面试题1.React渲染流程完整梳理整体分为三大阶段:协调(Render)、提交(Commit)、渲染绘制1.触发更新:setState、props变化、组件强制更新触发重渲染;2.Render阶段:构建虚拟DOM,执行Diff算法,对比新旧节点差异,生成更新队列,此阶段可被中断;3.Commit阶段:将Diff得到的差异批量更新到真实DOM,执行生命周期、副作用,不可中断;4.浏览器绘制:DOM变更后,浏览器执行重排重绘,更新页面视图。2.ReactDiff算法核心策略,为什么能高效对比?React为了降低Diff复杂度,做了三大预设策略,把O(n³)的复杂度降到O(n):1.同层比较:只对比同一层级节点,不跨层级对比,忽略节点层级移动的情况;2.类型优先:节点类型不同,直接销毁旧节点、创建新节点,不做复用;3.key精准匹配:同类型节点通过key唯一匹配,快速定位新旧节点,实现节点复用、移动、删除、新增。3.React18新特性及核心改进1.并发渲染:核心更新,支持任务优先级调度,可中断、恢复渲染,优先响应用户交互,解决页面卡顿;2.自动批量更新:统一所有场景的批量更新,定时器、Promise、原生事件中也会自动批量合并状态更新;3.新Hooks:useId、useTransition、useDeferredValue等,用于处理并发更新、延迟渲染、唯一ID生成;4.服务端渲染优化:支持流式SSR,提升首屏加载速度;5.严格模式升级:开发环境会重复执行副作用,提前暴露脏副作用、逻辑漏洞。4.什么是合成事件?和原生事件的区别合成事件是React封装的跨浏览器兼容事件系统,React并没有把事件绑定在真实DOM上,而是事件委托到根节点,统一捕获、处理事件。区别:1.兼容性:合成事件统一抹平浏览器兼容问题,原生事件需要自行处理兼容;2.绑定方式:合成事件事件委托,性能更好,动态节点无需重复绑定;原生事件直接绑定在DOM节点;3.执行时机:合成事件在React批量更新流程中执行,原生事件不受React管控;4.阻止冒泡:合成事件的stopPropagation只能阻止合成事件冒泡,无法阻止原生事件冒泡。四、性能优化实战面试题1.项目中React性能优化你做过哪些?整理日常落地的优化手段,贴合实战:1.组件优化:用memo缓存函数组件,避免无意义重渲染;类组件用PureComponent/shouldComponentUpdate做浅对比拦截更新;2.数据与函数优化:useMemo缓存复杂计算,useCallback缓存事件函数,配合memo实现精准更新;3.列表优化:唯一key、虚拟列表(react-window/react-virtualized)处理万级长列表,减少DOM节点数量;4.路由优化:路由懒加载、代码分割,拆分打包文件,减小首屏包体积;5.资源优化:图片懒加载、静态资源CDN、去除冗余依赖、压缩打包资源;6.事件优化:事件委托、销毁组件时清除定时器、监听事件,防止内存泄漏;7.渲染优化:避免内联函数、内联对象,防止每次渲染生成新引用导致组件更新。2.如何避免React内存泄漏?常见场景和解决方案常见泄漏场景:定时器、延时器、事件监听、网络请求订阅、全局订阅、第三方实例未销毁。解决方案:在useEffect的清理函数中统一销毁资源。组件卸载时,清除定时器、移除事件监听、取消请求、销毁第三方实例。举例:接口请求在组件卸载后仍执行setState,会报内存泄漏警告,可通过声明取消请求标识,在清理函数中中断请求。五、Router+状态管理面试题1.ReactRouter中hash模式和history模式区别1.hash模式:基于url#哈希值变化,哈希变化不会触发页面刷新,兼容性好,不需要后端配置;缺点是url带#,不够美观,部分场景不友好。2.history模式:基于H5historyAPI,url干净无#,体验更好;缺点是刷新页面会请求后端地址,需要后端配置重定向,否则会报404。2.Redux核心流程、为什么需要单向数据流?核心流程:视图触发Action→Reducer接收Action→根据Action类型修改State→Store更新状态→视图响应更新。单向数据流的意义:数据流向清晰、可追溯,所有状态变更都经过统一的reducer处理,避免随意修改状态导致的逻辑混乱、bug难以定位,适合中大型项目统一管理全局状态。3.Redux、Mobx、Context+useReducer如何选型?1.小型项目、状态简单:用Context+useReducer,无需引入第三方库,轻量化;2.中大型项目、状态复杂、需要可追溯、团队协作规范:用Redux/Toolkit,统一状态管理,逻辑清晰;3.快速开发、不想写冗余模板代码:用Mobx,响应式更新,代码简洁灵活。六、实战坑点与手写面试题1.说说useEffect常见踩坑点1.依赖项缺失导致闭包陷阱,获取到旧的state/props值;2.未清理副作用导致内存泄漏、重复请求、重复监听;3.依赖项写引用类型(对象、数组),导致无限循环渲染;4.开发环境严格模式下副作用重复执行,未做幂等处理导致逻辑异常。2.手写:React组件防抖函数(hooks版)javascript

import{useCallback,useRef}from'react'

//自定义防抖Hook

exportdefaultfunctionuseDebounce(fn,delay=300){

consttimerRef=useRef(null)

constdebounceFn=useCallback((...args)=>{

if(timerRef.current){

clearTimeout(timerRef.current)

}

timerRef.current=setTimeout(()=>{

fn(...args)

},delay)

},[fn,delay])

returndebounceFn

}3.手写:简单useState模拟实现javascript

//简易版useState原理模拟

letstate=null

letrender=null

functionmyUseState(initialValue){

//首次赋值

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论