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

前端经典react面试题(持续更新中)

时间:2023-03-28 19:45:10 HTML

React一定要用JSX?React不强制使用JSX。当您不想在构建环境中配置JSX编译时,在React中不使用JSX会更方便。每个JSX元素只是调用React.createElement(component,props,...children)的语法糖。因此,任何可以用JSX完成的事情都可以用纯JavaScript来完成。例如,用JSX编写的代码:classHelloextendsReact.Component{render(){return

Hello{this.props.toWhat}
;}}ReactDOM.render(,document.getElementById('root'));可以写成不使用JSX的代码:}}ReactDOM.render(React.createElement(Hello,{toWhat:'World'},null),document.getElementById('root'));用户如何查看不同权限的不同页面?Js方法根据用户权限类型将菜单配置为json,react-router方法不会根据用户权限类型直接显示菜单。react-router方法在路由标签中添加onEnter事件,并在进入路由前将其替换为首页。{if(nexState.location.pathname!=='/'){varsid=UtilsMoudle.getSidFromUrl(nexState);if(!sid){replace("/")}else{console.log(sid);}}}}>封装一个privateRouter组件,判断是否有权限,有则返回如果没有权限,组件会返回提示信息拓展一下,如果我们根据权限判断是否隐藏组件怎么办?React可以使用高级组件,判断高级组件中是否有权限,然后判断是否返回组件,没有权限则返回nullVue可以使用自定义指令,如果没有权限则移除组件//需要在入口添加自定义权限指令v-auth,显示可操作组件Vue.directive('auth',{bind:function(el,binding,vnode){//用户权限表construles=authsfor(leti=0;i
添加用户删除用户编辑用户
react渲染过程中,兄弟节点是怎么处理的?也就是当key值不同的时候,通常我们在输出节点的时候,会映射一个数组,返回一个ReactNode。为了便于react内部优化,我们必须给每个reactNode添加一个key。此关键道具不按设计值开发。是作者用的,不过是为了react,大概是为了用途是为每个reactNode添加一个标识,方便react进行标识。在重新渲染过程中,如果key相同,如果组件属性发生变化,react只会更新组件对应的属性;如果没有变化,则不会更新。如果key不一样,则react先销毁组件,再重新创建组件。调用setState后会发生什么?在代码中调用setState函数后,React会将传入的参数与之前的状态进行合并,然后触发所谓的调和过程(Reconciliation),调和过程之后,React会根据中的新状态构建React元素树一种相对高效的方式,并开始重新渲染整个UI界面。React拿到元素树后,React会计算新旧树的差异,然后根据差异最小化并重新渲染界面。通过diff算法,React可以准确地指导哪些位置发生了变化以及应该如何变化,从而确保按需更新而不是完全重新渲染。setState时,React会为当前节点创建一个updateQueue的更新队列。然后将触发对帐过程。在此过程中,将使用一种称为Fiber的调度算法开始生成新的Fiber树。Fiber算法最大的特点就是可以异步、可中断地执行。然后ReactScheduler会根据优先级优先执行优先级高的节点,具体执行doWork方法。在doWork方法中,React会执行updateQueue中的方法获取新的节点。然后比较新旧节点,并用更新、插入和替换标记旧节点。当前节点的doWork完成后,会执行performUnitOfWork方法获取新的节点,然后重复上述过程。当所有节点都完成doWork后,会触发commitRoot方法,React进入commit阶段。在commit阶段,React会为每个节点根据之前的Tag一次性更新整个dom元素key。key的作用是给每个vnode一个唯一的id。可以依靠key更准确更快的获取oldVnode中对应的。vnodenode
ka

song
songka

如果没有key,React会考虑第一个子节点div从p到h3,以及从h3到p的第二个子节点,这两个节点会被销毁重建。但是当我们用key指定节点前后关系时,React知道更新后key==="ka"的p还在,所以可以复用节点,只需要顺序需要交换。key是一个辅助标志,React使用它来跟踪哪些列表元素已被修改、添加或删除。在开发过程中,我们需要保证一个元素的key在其兄弟元素中是唯一的。在Reactdiff算法中,React会根据元素的Key值来判断元素是新建还是移动,从而减少不必要的元素重新渲染。同时,React还需要使用key来判断元素与本地状态的关系。说说用react有什么坑?1、JSX中判断表达式时,需要强制为boolean类型。如果不使用!!b强制数据类型,页面中会输出0。渲染(){常量b=0;return
{!!b&&
Thisisapieceoftext
}
}2.componentWillReviceProps中尽量不要使用setState,如果一定要,那么需要判断结束条件,否则会无限重渲染,导致页面崩溃3.在给组件添加ref的时候,尽量不要使用匿名函数,因为当组件更新时,匿名函数会被当作一个新的prop,让ref属性当接收到一个新的函数时,react内部会清空ref,即以null为回调参数执行一次refprops,然后以组件的实例执行一次ref,所以当使用匿名函数作为ref时,有去ref赋值时,赋值后的属性会为null4。遍历子节点时,不要使用index作为传入组件的key。refs的作用是什么,你在什么样的业务场景,详见前端高级面试题解答。接下来,使用refs来操作DOM。为什么要操纵DOM?场景图像渲染完成后,操作图像的宽度和高度。比如virtualdom为什么要通过做放大镜的功能来提升性能?virtualdom相当于在js和realdom之间加了一个cache,利用domdiff算法避免不必要的dom操作,从而提高性能。具体实现步骤如下:使用JavaScriptobjectstructure表示DOM树的结构;然后使用这棵树构建一个真正的DOM树并将其插入到文档中;当状态改变时,重建一个新的对象树。然后比较新树和旧树,记录两棵树的不同;将步骤2中记录的差异应用到步骤1中构建的真实DOM树,视图将被更新。setState是异步的还是同步的?先给出答案:有时会出现异步,有时会出现同步。setState只是在合成事件和钩子函数中是“异步的”,setState是“异步的”,在nativeevents和setTimeout中是同步的,并不是说内部实现是用异步代码实现的,其实执行过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致合成事件和钩子函数中无法立即获取更新值,形成所谓的“异步”。当然,更新后的result可以通过第二个参数setState(partialState,callback)中的回调获取。setState的批量更新优化也是基于上面的“异步”(合成事件,钩子函数),不会在native事件中批量更新还有setTimeout,在“异步”中,如果对同一个值多次执行setState,setState的批量更新策略会覆盖掉,最后一次执行采取。如果是同时,setState有多个不同的值,更新的时候会合并,分批更新。react-router4的核心路由变成组件分散到各个页面,不需要配置如ReactlifecycleFunctionMountPhasemount阶段也可以理解为初始化阶段,也就是将我们的组件插入到DOM中。constructorgetDerivedStateFromProps~~UNSAFE_componentWillMount~~render(ReactUpdatesDOMandrefs)componentDidMountconstructor组件的构造函数最先被执行。显式定义构造函数时,需要在第一行执行super(props),否则无法在构造函数中获取this。在构造函数中,我们一般会做两件事:初始化状态,将this绑定到自定义方法getDerivedStateFromProps是一个静态函数,所以这里不能使用this,这也说明React官方不希望调用者滥用这个生命周期函数。getDerivedStateFromProps会在每次父组件触发当前组件的renderpass时被调用,让我们有机会根据新的props和当前状态调整新的状态。当收到新的props时,将调用此函数,调用setState或forceUpdate。renderReact的核心方法,必须在类组件中实现的方法。当调用render时,它会检查this.props和this.state是否发生变化并返回以下类型之一:原生DOM,例如divReact组件数组或FragmentPortals(门户)字符串或数字,呈现为文本节点布尔值或null,什么都不会呈现componentDidMount在组件安装后立即被调用。依赖于DOM节点的初始化应该放在这里。如果您需要通过网络请求获取数据,这是实例化请求的好地方。这种方式更适合添加订阅。如果您添加了订阅,请记得在卸载时取消订阅。可以在componentDidMount中直接调用setState,会触发额外的渲染,但是这个渲染会发生在浏览器更新屏幕之前,这样即使渲染了两次,用户也看不到中间状态。更新阶段更新阶段是指组件的props发生了变化,或者组件内部调用了setState,或者发生了forceUpdate。这个阶段的过程包括:UNSAFE_componentWillReceivePropsgetDerivedStateFromPropssholdComponentUpdateUNSAFE_componentWIllUpdaterendergetSnapshotBeforeUpdate(ReactUpdatesDOMandrefs)componentDidUpdateshouldComponentUpdate根据这个函数有两个参数返回值用来判断是否重新渲染。此方法不会在第一次渲染或调用forceUpdate时触发。该方法仅用于性能优化。但是官方提倡我们使用内置的PureComponent,而不是自己写shouldComponentUpdate。生命周期函数getSnapshotBeforeUpdate发生在渲染之后。在更新之前,它提供了一个获取DOM信息的机会,计算并返回一个快照,作为componentDidUpdate的第三个参数传入。componentDidUpdate函数会在更新后立即调用,第一次渲染不会执行该方法。在这个函数中,我们可以操作DOM,发起请求,setState,但是要注意使用条件语句,否则会导致死循环。unmount阶段的生命周期函数componentWillUnmount会在组件被卸载销毁前被调用。我们可以在这里进行一些清理操作。不要在这里调用setState,因为组件不会重新渲染。Hooks可以替代renderprops和高阶组件吗?通常,renderprops和高阶组件只渲染一个子组件。React团队认为Hooks是服务于此用例的更简单方法。这两种模式都有它们的位置(例如,一个虚拟滚动组件可能有一个renderItem属性,或者一个可视化容器组件可能有它自己的DOM结构)。但在大多数情况下,Hooks就足够了,可以帮助减少树中的嵌套。setState是同步的还是异步的?有时它是同步的,有时它是异步的。setState只在React自己的合成事件和钩子函数中是异步的。它在本机事件和setTimeout中是同步的。setState的异步并不意味着它是内部控制的。异步代码实现,其实执行过程和代码是同步的,只是在合成事件和钩子函数中不能立即获取到更新的值,形成了所谓的异步。当然也可以通过setState的第二个参数中的回调获取更新后的结果。setState的批量更新优化也是基于异步的(合成事件,钩子函数),不会在native事件和setTimeout中批量更新。如果在异步模式下为同一个值设置了多次setState,setState的批量更新策略会覆盖掉它,转到最后一次执行。如果同时设置了多个不同的setState值,在更新时会合并并批量更新,合成事件是异步的。钩子函数是异步的。本机事件是同步的。setTimeout是同步的。redux实现原理分析为什么要用redux。在React中,数据在组件中是单向流动的,数据从父组件到子组件是单向流动的(通过props),所以两个非父子组件之间的通信比较麻烦。redux的出现就是为了解决状态下的数据问题。Redux的设计理念Redux将整个应用程序的状态存储在一个叫做store的地方,存储了一个状态树storetree,组件可以将action派发到store而不是直接通知其他组件。组件通过订阅store中的状态state在内部刷新自己的视图。Redux的三大原则是整个应用的唯一数据源。state的状态存储在一个statetree中,这个statetree只存在于唯一的store中,保持只读状态。状态是只读的。改变状态的唯一方法是触发一个动作。普通时间对象的数据更改只能通过纯函数来完成。使用纯函数来执行修改。为了描述动作如何改变状态,你需要写reducersRedux源代码letcreateStore=(reducer)=>{letstate;//获取状态对象//存储所有监听函数letlisteners=[];让getState=()=>状态;//提供外部调用dispatchactions的方法letdispatch=(action)=>{//调用administratorreducer获取新的一个statestate=reducer(state,action);//执行所有的监听函数listeners.forEach((l)=>l())}//订阅状态变化事件,当状态变化发生时执行监听函数letsubscribe=(listener)=>{listeners.push(listener);}dispath();return{getState,dispath,subscribe}}letcombineReducers=(renducers)=>{//传入一个reducers管理组,返回一个reducerreturnfunction(state={},action={}){letnewState={};for(reducers中的varattr){newState[attr]=renducers[attr](state[attr],action)}returnnewState;}}出口{createStore,combineReducers};告诉我什么是JSX?当Facebook首次发布React时,他们还引入了一种新的JS方言JSX,它将原始HTML模板嵌入到JS代码中。JSX代码本身不能被浏览器读取,必须使用Babel和webpack等工具对遗留JS进行转换。许多开发人员可以在没有意识到的情况下使用JSX,因为它已经与React集成在一起。MyComponent类扩展了React。Component{render(){让props=this.道具;return({props.name}
);}}如何避免重复启动ajax获取数据?数据放在redux中什么是高阶组件(HOC)高阶组件(HigherOrderComponent)本身不是一个组件,而是一个函数,这个函数接收一个元组件作为参数,然后返回一个新的增强组件,高阶组件的出现也是为了逻辑复用。例如,函数withLoginAuth(WrappedComponent){returnclassextendsReact.Component{constructor(props){super(props);this.state={isLogin:false};}asynccomponentDidMount(){constisLogin=awaitgetLoginStatus();this.setState({isLogin});}render(){if(this.state.isLogin){return;}return(
你还没有登录...
);}}}什么是虚拟DOM?虚拟DOM(VDOM)是真实DOM的内存表示。UI的表示保存在内存中并与实际的DOM同步。这是在渲染函数被调用和元素被显示在屏幕上之间发生的一个步骤,整个过程称为协调。React的虚拟DOM和Diff算法的内部实现传统的diff算法的时间复杂度是O(n^3),这在前端渲染中是无法接受的。为了降低时间复杂度,react的diff算法做了一些折衷,放弃了最优解,最终将时间复杂度降低到O(n)。那么reactdiff算法做了哪些妥协呢?,参考如下:treediff:只比较同层的dom节点,忽略dom节点的跨层移动。当发现该节点不存在时,该节点及其子节点将被彻底删除,不再用于进一步的比较。这样只需要遍历一次树就可以完成整个DOM树的比较。这意味着如果dom节点跨层移动,react将删除旧节点并生成新节点而不会重复使用。Componentdiff:如果不是同类型的component,则删除旧的component,创建一个新的component。elementdiff:对于同一层级的一组子节点,需要通过唯一的id来区分。如果没有id区分,一旦有插入动作,就会导致插入位置之后的所有列表重新渲染,这就是为什么在渲染列表的时候要用一个唯一的key。React中的元素和组件有什么区别?简单地说,React中的元素(虚拟DOM)描述了你在屏幕上看到的DOM元素。换句话说,React中的元素是页面中DOM元素的对象表示。React中的组件是接受输入并返回元素的函数或类。注意:在工作中,为了提高开发效率,通常使用JSX语法来表示React元素(虚拟DOM)。在编译时,将其转换为React.createElement调用方法。