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

前端面试资料整理【React篇】

时间:2023-03-28 12:57:17 HTML

React参考React源码React为什么JSX实用?萝卜青菜,各有所爱。但是react团队认为模板方案不好:模板分离了技术栈,增加了技术点。看起来像html的jsx。react的规则太强了,需要jsx来辅助。比如在使用vue时,上面是html模板,下面是js逻辑组成一个组件功能。但是React在一个类中同时运行html和运行逻辑。JSX是如何映射虚拟DOM的?JSX是creatElement的语法糖,使用了babel的escaper。其实是通过两个方法完成的,一个是createElement,一个是reactElement//定义一个react对象reactElement(type,key,ref,self,source,ReactCurrentOwner.current,props)RreactDFMDataDrivenView?UI=render(data)数据和状态有什么区别?状态(state)和数据(data),组件中的通信是数据的通信,react的核心是数据的管理数据流:父->子->父兄无关系单向数据flowMVC双向数据流的缺点。造成混乱。Action->Dispatcher->Store->View|--------<--------Action<-|ACTION视图层redux发送的消息是js的状态容器Action->Reducer->Store[state,state]|--------<------View--<-|redux优缺点缺点:使用过程复杂。状态不会随组件一起销毁,状态会一直存在。商店经常更新时,会比较卡。不支持ts。mobx的原理是利用es6代理数据劫持,使用redux也不会??复杂。ReactFiber将在16毫秒后丢帧。原来React是使用js的执行栈,一直执行到栈空的位置。新版本的React维护了自己的执行栈,通过链表的形式遍历树结构来优化执行过程。参考虚拟DOM和diff算法VirtualDOMReact是一种渲染dom的优化方法。原理是使用createFragment,即“创建片段”。所有的DOM操作都会以“片段”的形式进行,直到操作完成,然后一起渲染。diff算法是React更新dom元素的一套算法。其核心思想是对“节点树”的每个节点进行比较,根据比较结果决定是否更新该节点。通过其优化方法,更新树的时间复杂度从O(n^3)变为O(n)。diff策略忽略跨组件移动操作。相似的组件创建同一棵树,不同类型创建不同类型的兄弟(ReactComponent和functionComponent)。key分为3种更新策略:treediff、componentdiff、elementdiff:treediff:遇到树结构更新时,只比较同级节点,只创建和删除子节点。这意味着如果有中间节点移动某个树结构,原树会直接删除该节点及其子节点,并在新树中创建该节点及其子节点。另外,官方不建议跨节点进行移动操作。Componentdiff:当一个节点更新为不同类型的节点时,它就变成了脏组件。React认为不同类型的一个更新节点的结构一定是不同的(树结构),所以直接删除节点,直接创建。elementdiff:计算兄弟节点的直接移动操作。将原来删除并重新创建目标节点的更新策略改为通过标识key来判断是否为原始节点。此外,它还获得了判断是否发生移动操作的依据。由此得出3条优化建议:设置key,不要将组件更新为不同的类型,减少将兄弟组件从尾部移到头部的操作,参考Redux待补充React优化常见优化详解:function组件而不是类组件->为什么?参考1参考2HOC在使用redux等状态管理工具时,一些不常用的状态不需要挂载到模型中-->为什么?首屏优化方案lazy延迟加载组件react-router加载提升体验ssr(服务端渲染)和csr(客户端渲染)pureComponent和shouldUpdate优化更新频率componentDidCatch检测错误边界通过render函数中的Fragment变量声明减少标签深度提升外出,减少GCReact-HooksuseState相当于类组件中的setState。functionrender(){ReactDom.render(,document.getElementById('root'))}functionmyState(initState){让state=initStateconstupdate=(newState)=>{state=newStaterender()}return[state,update]}functionApp(){}useEffect相当于类组件中的几个生命周期函数16.8为什么要加Hook?或者为什么要添加功能组件?在类组件中重用状态可能很困难。HOC虽然解决了,但是存在嵌套地狱的问题。如果类组件生命周期发生变化,其他生命周期可能也需要改变。es6的class不如function,对初学者比较友好。这点官方回答要站在设计者的角度去思考。SSRnext主要用在React中。npxcreate-next-appreact-router是根据历史开发的无刷新路由器。主要有三种类型:hashHistory、borrowerHistory和memoryHistory。常用的有hashHistory和browerHistory。新版本是react-router-dom,importReactfrom"react";import{Router}from"react-router";import{createBrowserHistoryascreateHistory}from"history";importPropTypesfrom"prop-types";importwarning来自"tiny-warning";/***使用HTML5历史记录的的公共API。*/classBrowserRouterextendsReact.Component{history=createHistory(this.props);render(){return;}}导出默认浏览器路由器;browerHistory和hashHistory的区别是hash路由根据#后面的锚点刷新,通过window.onhashChange监听变化,根据路由找到对应的文件,history是通过html5的webAPI实现的窗口.历史。hashHistory的特点:使用了history.location.hash,即history.location.hash="abc"(相当于localhost/#abc)只能通过修改#后面的地址来刷新,通过window监听hash变化.onhashchange,window.addEventListener('onhashchange',hashchangeHandler)想不到window.history.go(-1)是这样的,只能通过字符串改url,对搜索引擎不友好,不容易跟随追溯browerHistory的特点:使用History对象,提供go、back、forward方法,相同的url会被更新,通过push和replace方法推送到history中,实际上是通过pushState、replaceState实现之间的无刷新跳转其中pushState会被压入浏览器历史栈中,即History.length+1,replaceState不会。问题使用history更新路由正常渲染,然后刷新,会导致404。(待验证)是因为history更新了url,也就是访问地址。这时候向后端服务器请求时,如果没有匹配到该地址的资源,就会是404。比如nginx配置/test地址访问。通过历史路由器从/test跳转到/say。刷新的时候,服务端会找不到资源,可以通过配置父路径来避免。window.location也会更改url但会导致刷新