react面试题
2024-03-10 22:08:25
浏览量: 1018
01
- hoc高阶函数、高阶组件
- 抽离重复代码,实现组件复用
- 条件渲染、渲染拦截
- 属性代理
- React Router/ react-router-dom中有哪些组件?
- BrowserRouter:用于在应用程序中启用HTML5历史路由。
- HashRouter:用于在应用程序中启用哈希路由。
- Route:用于定义应用程序中的路由规则。
- Switch:用于在多个路由规则中选择一个。
- Link:用于在应用程序中导航到其他页面。
- Outlet:路由嵌套时,渲染二级路由
- react-router-dom新api
import { lazy, Suspense } from 'react'//使用lazy进行路由组件赖加载
import { createBrowerRouter, createHashRouter, RouterProvider } from 'react-router-dom'
const Comp = lazy(()=>import('./Comp'))
const router = createBrowerRouter([
{path: '', element: <Suspense fallback={'loading'}><Comp/></Suspense>}
])
<RouterProvider router={router} />
- Redux中有哪些核心概念?
- Store:通过createStore来创建Store,把action和reducer关联到一起,通过store.subscribe注册监听
- State:状态数据
- Action:用于描述发生的事件。
- Reducer:用于处理Action并更新状态。
- Dispatch:用于将Action发送到Reducer。
- redux本身无法处理异步请求,但是它提供了中间件机制以扩展redux功能
- redux-looger 日志输出中间件
- redux-thunk 处理异步中间件
- redux-saga 使用Generator生成器和iterator迭代器处理异步中间件
- 如何在React中使用Redux?
- 安装Redux和react-redux。
- 创建一个Redux store。
- 创建一个Reducer来处理Action并更新状态。
- 通过Provider向组件注入store
- 使用connect()函数接受数据和dispatch
// userReducer.js
export default (state={num:0}, action) => {
switch(action.type){
case 'add':
return {...state,num: state.num+action.num};
default: return state;
}
}
//indexStore.js
import { createStore, combineReducers, applyMiddleware } from 'redux'
import userReducer from './userReducer.js'
import reduxThunk from 'redux-thunk'
const store = createStore(
combineReducers({ user:userReducer }),
applyMiddleware(reduxThunk)//使用中间件支持异步操作后
)
//入口main.js
import { Provider } from 'react-redux'
import store from './store'
ReactDom.render(
<Provider store={store}><App/></Provider>,
document.getElementById('root')
)
//在类组件中使用
import { connect } from 'react-redux'
class MyComp extends Component {
render(){
<div onClick={this.props.padd(1)}></div>
}
}
export default connect(
state=>{ return { num:state.user.num } },
dispatch=>{ return {
padd(num){ dispatch({type:'add',num}) }
} }
)(MyComp)
//在函数组件中使用
import { useSelector, useDispatch } from 'react-redux'
const userState = useSelector(state=>state.user)
const dispatch = useDispatch()
dispatch({type:'add',1})
- 使用@reduxjs/toolkit。默认支持异步操作
import { createSlice, configureStore } from '@reduxjs/toolkit'
const user = createSlice({
name: 'user',
initialState:{},
reducers:{
add(state,action){}
}
})
export const { add } = counterSlice.actions
export default counterSlice.reducer
// 使用const store = configureStore({ reducer:user })进行模块化合并
//封装异步函数,操作action
export const acAdd = () => {
return async (dispatch) => {
// const res = await axios.get('xxx')
dispatch(add(res))
}
}
// 在组件中
dispatch(add('xxx'))//xxx会被传递到action对象的payload属性上
dispatch(acAdd())
- redux applyMiddleware 中间件原理
function midw(store){
const raw = store.dispatch
return function(action){
// action.toString() === 'async function(){}'
if(action.constructor.name === 'AsyncFunction'){
action(raw)//异步函数
}if(typeof action === 'function'){
raw(action())
} else if (typeof action === 'object'){
raw(actionObj)
}
}
}
function chain(...midws){
midws.forEach(m => {
store.dispatch = m(store)
})
}
chain(midw,midw2,midw3)
- React Hooks有哪些?
- useState()
- useEffect()
- 无依赖项时,初始执行一次,dom更新时执行
- 依赖空数组时,仅初始化执行一次
- 依赖非空数组时,初始执行一次,数组中的数据变化即执行
- useContext()
- useReducer()
// a.js
const Ctx = createContext({})
const reducer = (state={},action)=>{
switch(action.type){
case 'add':
return {...state,num: state.num+action.num};
default: return state;
}
}
//b.jsx
const [store,dispatch] = useReducer(reducer,dState)
<Ctx.Provider value={{store,dispatch}}><Comp/></Ctx.Provider>
//c.jsx
const { store,dispatch } = useContext(Ctx)
- useCallback(()=>{},[]) 缓存一个函数
- useMemo(()=>{return xxx},[]) 缓存函数运行的结果
- useRef() 获取dom结构或组件实例
- useImperativeHandle()配合React.forwardRef在函数组件中自定义暴露给父组件的实例值。这可以用于创建可重用的组件。
- useLayoutEffect()它类似于useEffect(),但是它在DOM更新之前同步触发。这可以用于处理需要同步更新DOM的情况。
- useDebugValue()它允许我们在React开发工具中调试自定义Hooks的值。
- 规则
- hooks函数只能在组件或自定义hook函数中使用
- 必须在组件顶层使用,不能用在if或for中
- -e
- react路由守卫
- React没有路由守卫,但是我们可以通过高阶组件实现相关功能,使用方法如下
import React from 'react'
import {Navigate, useLocation, useParams, useSearchParams} from "react-router-dom";
import Cookie from "js-cookie";
// useParams 获取占位符传参,useSearchParams获取query传参
type RouteProps = {
children?: React.ReactNode
}
const loginRoute = '/login'
const indexRoute = '/'
// 路由表白名单
const allowList = ['/login', '/register']
const AuthRoute: React.FC<RouteProps> = (props) => {
const location = useLocation();
const {children} = props
let token = Cookie.get('token')
if (token && token !== 'undefined') {
if (location.pathname === loginRoute) {
return <Navigate to={indexRoute}></Navigate>
} else {
return <>{children}</>
}
} else {
if (allowList.includes(location.pathname || '')) {
return <>{children}</>
} else {
return <Navigate to={loginRoute}></Navigate>
}
}
}
export default AuthRoute
//---------------------------------------------
// 引入路由表
import {BrowserRouter, Switch, Route} from 'react-router-dom';
// 引入实现路由鉴权的高阶组件
import AuthRoute from "@/components/Auth/AuthRoute";
const routerList = [{}]
const App = () => {
return (
<div className="App">
<BrowserRouter>
<AuthRoute>
<Switch>
{routerList.map((item,index) => <Route key={index} {...item}/>)}
</Switch>
</AuthRoute>
</BrowserRouter>
</div>
)
}
export default App
- 组件传参
- props
- 子组件调用props中的函数向父组件传参
- Context跨层传递
- 使用createContext创建一个上下文对象ctx, 并自定义一个 reducer 函数
- 在根/父组件中使用useReducer创建store和dipatch,并使用Ctx.Provider组件向下传递数据(store,dispatch)
- 在子组件中使用useContext钩子函数消费数据
02
- 什么是虚拟DOM?
- 虚拟DOM(VDOM)它是真实DOM的内存表示,一种编程概念,工作原理是通过js对象模拟DOM的节点。它会和真实的DOM同步,比如通过ReactDOM这种库,这个同步的过程叫做调和(reconcilation)。
- 以react为例,在render函数中写的jsx会在babel插件下,编译为React.createElement执行的JSX中的属性参数,React.createElement执行后会返回一个描述节点的对象,描述自己的tag类型,props属性以及children 子级等,这些对象通过树形结构组成一个虚拟DOM树,在状态发生改变时,对比更新前后虚拟DOM树的差异,这个过程称为diff,生成的结果称为patch,计算之后,会渲染patch完成对真实DOM的操作
- 虚拟dom结合ast抽象语法树的优势:
- 可以支持多端渲染
- 减少dom操作,提高性能
- 虚拟dom结合ast抽象语法树的区别
- 虚拟DOM其实就是一个普通的JS对象,根据虚拟节点渲染真是dom,会根据页面或数据的变化不断地更新,是为了提高页面渲染的性能。
- AST是通过对固定模版的插值表达式、指令等模板语句解析而编译而成的有规律的数据结构,是固定不变的,可以支持多端渲染
- 抽象语法树不会进行diff算法的并且抽象语法树不会直接生成虚拟节点,抽象语法树最终生成的是渲染函数的
- template --> 抽象语法树 --> render(h) --> 虚拟DOM-->UI
- 类组件和函数组件之间有什么区别?
- 类组件( Class components )
- 无论是使用函数或是类来声明一个组件,它决不能修改它自己的 props 。所有 React 组件都必须是纯函数,并禁止修改其自身 props 。
- React是单项数据流,父组件改变了属性,那么子组件视图会更新。属性 props 是外界传递过来的,状态 state 是组件本身的,状态可以在组件中任意修改组件的属性和状态改变都会更新视图。
- 函数组件(functional component)
- 函数组件接收一个单一的 props 对象并返回了一个React元素
- 区别
- 函数组件和类组件当然是有区别的,而且函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。为了提高性能,尽量使用函数组件。
- 区别函数组件类组件是否有this没有有是否有生命周期没有有是否有状态state没有有
- React中的refs作用是什么?
- Refs 是 React 提供给我们的安全访问 DOM 元素或者某个组件实例的句柄。
- 什么是JSX?
- JSX即JavaScript XML。一种在React组件内部构建标签的类XML语法。JSX为react.js开发的一套语法糖,也是react.js的使用基础。React在不使用JSX的情况下一样可以工作,然而使用JSX可以提高组件的可读性,因此推荐使用JSX。
- JSX是一种JavaScript的语法扩展,它允许我们在JavaScript中编写类似HTML的代码。它是React的核心之一,用于描述UI组件的结构和样式。
- ReactJS的生命周期方法是什么?
- componentWillMount: 在渲染之前执行,用于根组件中的应用程序级别配置。
- componentDidMount: 仅在客户端的第一次渲染之后执行。 这是AJAX请求和DOM或状态更新应该发生的地方。此方法也用于与其他JavaScript框架以及任何延迟执行的函数(如 setTimeout 或 setInterval )进行集成,在这里使用它来更新状态,以便我们可以触发其他生命周期方法。
- componentWillReceiveProps: 只要在另一个渲染被调用之前更新 props 就被调用。 当我们更新状态时,从 setNewNumber 触发它。
- shouldComponentUpdate: 确定是否将更新组件。默认情况下,它返回true。如果您确定组件在状态或道具更新后不需要渲染,则可以返回false值。这是提高性能的好地方,因为如果组件收到新的道具,它可以防止重新渲染。
- componentWillUpdate: 在由shouldComponentUpdate确认返回正值的优点和状态更改时,在重新渲染组件之前执行。
- componentDidUpdate: 通常用于更新DOM以响应属性或状态更改。
- componentWillUnmount: 它将用于取消任何传出的网络请求,或删除与该组件关联的所有事件侦听器。
03
- 说说react中的性能优化
- 使用shouldComponentUpdate来对state和props进行对比,如果两次的结果一直,那么就return false
- 使用纯净组件,pureComponent
- React.memo(组件,()=>{return ?})和pureComponent类似
- 高阶组件和高阶函数是什么
- 高阶函数:函数接收一个函数作为参数,或者将函数作为返回值的函数就是高阶函数 map some every filter reduce find forEach等等都属于高阶函数
- 高阶组价:接受一个组件,返回一个新组建的组件就是高阶组件,本质上和高阶函数的意思一样
- 高阶组件是用来复用react代码的一种方式
- setState和repalceState的区别
- setState 是修改其中的部分状态,相当于 Object. assign,只是覆盖,不会减少原来的状态;
- replaceState 是完全替换原来的状态,相当于赋值,将原来的 state 替换为另一个对象,如果新状态属性减少,那么 state 中就没有这个状态了
- setState是先存入state队列还是直接更新,根据isBatchingUpdates值判断,true则存入队列(异步),否则直接更新(同步)
- 在react可控制的事件里,是执行异步,如react的生命周期事件和合成事件(如onClick)
- 在react无法控制的事件,则执行同步,如原生事件、addEventListener、setTimeout等
- 什么是受控组件
- 受控组件就是可以被 react 状态控制的组件
- 在 react 中,Input textarea 等组件默认是非受控组件(输入框内部的值是用户控制,和React无关)。但是也可以转化成受控组件,就是通过 onChange 事件获取当前输入内容,将当前输入内容作为 value 传入,此时就成为受控组件。
- react父组件props变化的时候子组件怎么监听? componentWillReceiveProps(props) { console.log(props) this.setState({show: props.checked}) }
- React Component和Purecomponent区别
- Component 没有直接实现 shouldComponentUpdate 这个方法;但是 PureComponent通过浅层的Porps 和 state 的对比,内部实现了这个生命周期函数。
- PureComponent会跳过整个组件子树的props更新,要确保全部的子组件也是 pure 的形式。
- Component 中需要手动执行的 shouldComponentUpdate 函数,在PureComponent中已经自动完成了(自动浅对比)。
- PureComponent不仅会影响本身,而且会影响子组件,所以PureComponent最好用在数据展示组件中
- PureCoponent 如果是复杂数据类型,这里会造成错误的显示(setState浅复制更新,但是界面不会重新渲染)
- hooks相对于class的优化
- 类组件缺点一:复杂且不容易理解的“this”
- Hooks解决方式:函数组件和普通JS函数非常相似,在普通JS函数中定义的变量、方法都可以不使用“this.”,而直接使用该变量或函数,因此你不再需要去关心“this”了。
- 类组件缺点二:组件数据状态逻辑不能重用
- Hooks解决方式: 通过自定义Hook,可以数据状态逻辑从组件中抽离出去,这样同一个Hook可以被多个组件使用,解决组件数据状态逻辑并不能重用的问题。
- 类组件缺点三:组件之间传值过程复杂、缺点三:复杂场景下代码难以组织在一起
- Hooks解决方式:通过React内置的useState()函数,可以将不同数据分别从"this.state"中独立拆分出去。降低数据复杂度和可维护性,同时解决类组件缺点三中“内部state数据只能是整体,无法被拆分更细”的问题。
- 通过React内置的useEffect()函数,将componentDidMount、componentDidUpdate、componentWillUncount 3个生命周期函数通过Hook(钩子)关联成1个处理函数,解决事件订阅分散在多个生命周期函数的问题。
- react的render什么时候渲染?
- react生命周期有三个阶段。 两个阶段都会执行 render 主要从更新和挂载两个阶段来讲,挂载阶段都顺序,更新阶段一定要说shouldComponentUpdate true 和false 分别对应后边是否执行render
- useEffect的依赖为引用类型如何处理
- useEffect的依赖为饮用类型的时候,可能会导致监听不出发,原因就是监听的统一个地址的时候,对象本身地址没变,所以监听的结果就是认为数据并没有改变从而不直径调用
- react组件的key说一下 key发生变化会发生什么 key 值不同销毁前会触发什么生命周期
- react的key值给组件作为唯一标识,类似身份证,当数组发生增删改查的时候可以通过这个 标识来去对比虚拟dom的更改前后,如果相同标识的数据或者属性没有改变的话,讲直接略过,对比有改变的然后直接改变此项
- 如果给组件添加key,如果key值改变的时候,组件将会重新出创建会执行 挂在阶段的生命周期
- 知道react里面的createPortal么?说说使用场景。之前react没有这个的时候是怎么实现的,有他没他的区别
- react.createPortal 这个方法是来使用做弹窗Modal组件的,在没有这个组件之前我们可以自己定义组件,然后去实现Modal效果
- react.createPortal 这个来制作弹窗组件,它 在Modal 组件位置进行 fixed 定位,可以任意的挂载到某个dom元素上,使用后的管理更方便,但是注意需要预留html的挂载元素
- react全家桶
- 真正意义上的react全家桶,其实指的是react,react-dom,react-native。
- 因为react核心库只是vDom的操作,无关dom(dom操作在react-dom中)——这意味着它天生就可以做到跨平台。
- 注意这里有误区,react-router,react-router-dom,react-dux只是社区的一些使用较多的解决方案,事实上它们各有缺陷。
- 如何理解fiber?
- 截止到当前版本(react17.0.2),react尚存在一个明显的缺陷——这是大多数vDom框架都需要面对的——“diff”。
- 要知道,render前后的两颗vDom tree进行diff,这个过程是不可中断的(以tree为单位,不可中断),这将造成当diff的两颗tree足够庞大的时候,js线程会被diff阻塞,无法对并发事件作出回应。
- 为了解决这个问题,react将vDom节点上添加了链表节点的特性,将其改造成了fiber节点(其实就是vdom节点结合了链表节点的特性),目的是为了后面的Fiber架构的实现,以实现应对并发事件的“并发模式”。事实上,原计划是17版本上的,但最终定期在了18版本。
- 时间分片,任务分炼
- fiber节点的改造是为了将diff的单位从不可中断的tree降级到可中断的单一vDom。这意味着每次一个vDom节点比对过后,可以轮训是否发生了优先级更高的并发事件(react将用户想更快得到反馈的事进行了优先级排序,比如js动画等)。
- 每个vDom的比对是一个时间片单位,因此基于fiber节点的Fiber架构,存在这样的特性:“时间分片,任务分炼,异步渲染。”
- 你了解hooks吗?谈谈你对hooks的理解?聊聊hooks?
- react-hooks提供给了函数式组件以业务逻辑抽离封装的能力,从单一组件单位进行UI与业务逻辑的分离,以此来保证函数式组件的UI纯净。
- 在此之前,我们只能通过状态提升的方式,将业务逻辑提升到容器组件的方式。
- hooks使用规则?
- 只可以在顶层调用栈调用hooks,不可以在循环/条件/嵌套里调用hooks
- 只可以在react function或自定义hooks里调用hooks
- 原因见-27-hooks原理
- hooks原理
- react中的函数组件都有个基于Fiber数据结构的对象属性记录了该组件的渲染信息
- 每个hooks函数文件内部会向外暴露renderWithHooks用于函数组件在初始化或更新时调用,接收组件的Fiber对象属性,并保存起来
- 在hooks主函数被调用时,根据renderWithHooks中接收到的Fiber检测是否hooks记录表,有则新增hook节点,无则初始化记录表
- hooks的引用记录(调用记录表底层),是用单链表结构实现的;每一个链表节点(node)都有一个next的指针指向下一个node;如果被if条件打断,无法在组件初始化时构成完整的链表结构(会丢失链表node,导致hooks遍历中断)
- 在调用hooks更新函数时,先更改状态数据,再调用当前组件Fiber对象的更新函数更新视图
- useEffect与副作用?什么是副作用?聊聊useEffect?
- 副作用函数我们将跟UI渲染无关的业务逻辑称之为副作用。useEffect是react在函数式组件里提供的副作用解决方案,它接受两个参数。第一个是必传参数,类型为函数。我们写在此函数中的业务逻辑代码就是我们所说的副作用。
- 消除副作用函数:默认情况下,useEffct会在每次render后执行传入的副作用函数。然而有的时候我们需要在执行副作用前先去除掉上次render添加的副作用效果,我们可以在副作用函数里再返回一个函数———这个函数就是消除副作用,它会在每次reRender前和组件卸载时去执行。
- useEffect可以传入一个监听数组参数,这意味着副作用只有在数组中的监听值变化时才会执行。我们借助它的这个参数特性,可以模拟类组件生命周期钩子————比如componentDidMount等。
- useLayoutEffect?
- 与useEffect的区别是,useLayoutEffect中副作用的执行时间在组件render之前,这意味着它适用于比组件render更紧急的副作用。正因为如此,多数情况下我们不会选择使用它,因为我们并不想阻塞render。
- react组件设计模式
- react的组件设计模式分为 无状态组件(展示组件) 和有状态组件(灵巧组件)
- 无状态组件(展示组件)只作展示、独立运行、不额外增加功能的组件,特点是复用性强,可分为代理组件,样式组件,布局组件
- 有状态组件(灵巧组件)包含业务逻辑和数据状态的组件称为有状态组件,或者灵巧组件,特点是功能丰富、复杂度高、复用性低,有状态组件分为 容器组件和高阶组件
- 容器组件 - 几乎没有复用性,主要用于拉取数据和组合组件
- 高阶组件 - 实际是一个函数概念,一个函数可以接收另一个函数作为参数,然后返回一个函数,称为高阶函数
- 组件通信
- 单层级通信
- 父组件给子组件通信,传递props
- 子组件向父组件通信,使用回调函数
- 兄弟组件通信,通过父组件当中间件传递
- 跨多层组件通信
- React的context api
- 使用全局变量和事件,绑定在window
- 使用状态管理框架,如 redux
- 自定义事件订阅模式组件(不推荐,不好管理)
- react渲染流程
- 原理
- 基于babel.js将jsx转换为可被React.createElement函数所接受的dom节点树对象,然后被React.createElement生成虚拟DOM
- 如果是Html节点则直接render,如果是自定义组件则基于React.Component实现自定义组件的解析
- ReactDOM.render 基于虚拟DOM渲染或更新真实DOM,更新时做diff差值对比计算
- react16以后的渲染流程是Fiber架构
- 将所有的dom节点映射为fiber对象,使用特殊的链表取代了树是一种fiber数据结构,其有三个指针,分别指向了父节点、子节点、兄弟节点
- createRoot:创建FiberRoot(全局唯一,保存全局状态)和RootFiber(是应用里的第一个fiber对象),并将其关系关联起来
- render:主要是通过调用updateContainer,基于fiber对象将组件渲染在页面上。
- Fiber架构特点
- 协作性多任务模式 - 线程会定时放弃自己当前运行权利,交给主线程运行
- 策略性优先级 - 调度任务通过标记tag的方式区分优先级执行
- 渲染过程基本可以划分为 Render 和 Commit 两个阶段
- Render 阶段主要是计算出diff树,自下而上逐个节点检查并构造新的树,特点是可终止
- Commit 阶段是根据diff更新DOM树,回调生命周期等,同步执行,不可中断暂停
- 受控组件和不受控组件
- 受控组件
- 每当表单状态发生变化时,都会被写入组件的state中,这种组件成为受控组件
- 受控组件和不受控组件区别
- 受控组件:没有维持自己的状态,状态由父组件控制,仅通过父组件的props获取当前值,然后通过回调函数通知更改
- 不受控组件:保持着自己的状态,refs用于获取当前值
- Filber是什么
- fiber 是一个链表结构,它有三个指针,分别记录了当前节点的下一个兄弟节点,子节点,父节点。当遍历中断时,它是可以恢复的,只需要保留当前节点的索引,就能根据索引找到对应的节点。
- 在 Fiber 架构中 React 放弃了递归调用,采用循环来模拟递归,因为循环可以随时被中断。
- Fiber 将大的渲染任务拆分成一个个小任务
- React 使用 requestIdleCallback 去利用浏览器的空闲时间去执行小任务,React 在执行一个任务单元后,查看是否有其他高优先级的任务,如果有,放弃占用线程,先执行优先级高的任务。
- requestAnimationFrame 会在下一帧动画上调用高优先级的任务
- 在函数组建中封装强制更新组件的hooks
function MyForceUpdate(){
const [_, _Update] = useReducer(x=>x, 0);//旧版本中useState和useReducer都需要数据每次变化才会触发组件更新,新版本中的useReducer不需要改变数据也会触发组件更新
return ()=>{ _Update() }
}
- react状态管理库
- redux 是 JavaScript 状态容器,提供可预测化的状态管理。可运行于不同的环境(客户端、服务器、原生应用),属于发布订阅模式
- Mobx 强调响应式和自动的状态更新机制,通常采用观察者模式。
- Recoil 由facebook开发和react属于同一家公司,专门用于管理react程序的状态,提供了一些Hooks和选择器来读取和更新状态
- vue和React diff 算法的原理
- 同一层级的节点进行比较:React 只会比较同一层级的节点,如果节点在不同的层级,React 会直接销毁旧节点并创建新节点。这是基于 Web 应用的特性:跨层级的节点移动操作在实际应用中相对较少。
- 不同类型的元素会产生不同的树:如果两个元素的类型不同,React 会直接销毁旧元素及其子元素,并创建新元素。例如,一个 <div> 元素不能变成 <span> 元素。
- 通过 key 属性进行区分:如果两个元素的类型相同,React 会比较它们的 props 来决定是否更新。对于列表元素,React 使用 key 属性来区分不同的元素。如果 key 不变,React 认为这是同一个元素,只会更新这个元素的 props;如果 key 变了,React 会销毁旧元素并创建新元素。
- vue比对节点,当节点元素类型相同,但是className不同,认为是不同类型元素,删除重建,而react会认为是同类型节点,只是修改节点属性
- vue的列表比对,采用从两端到中间的比对方式,而react则采用从左到右依次比对的方式。当一个集合,只是把最后一个节点移动到了第一个,react会把前面的节点依次移动,而vue只会把最后一个节点移动到第一个
- react有了Fiber架构后结合diff算法,性能有了很大提升
推荐文章
-
2024-02-18 04:56:39 浏览量: 1014
-
2024-03-06 15:35:55 浏览量: 1103
-
2024-02-07 03:15:48 浏览量: 1007
-
2024-02-08 17:17:29 浏览量: 1006
-
2024-02-16 14:02:15 浏览量: 1007
-
2024-02-23 17:39:12 浏览量: 1011
-
2024-03-02 09:11:40 浏览量: 1009
-
2023-11-26 13:04:03 浏览量: 1014
-
2024-01-07 23:57:59 浏览量: 1015
-
2024-02-15 20:56:24 浏览量: 1004
-
2024-02-15 19:22:53 浏览量: 1015
-
2024-03-10 22:08:25 浏览量: 1018
-
2024-03-08 07:49:06 浏览量: 1017
-
2024-03-10 22:07:00 浏览量: 1010
-
2024-03-10 22:08:00 浏览量: 1004
-
2024-02-29 09:32:30 浏览量: 1009
-
2024-02-15 18:21:12 浏览量: 1003
-
2024-02-29 10:53:44 浏览量: 1006
-
2024-02-15 23:08:03 浏览量: 1002
-
2024-03-10 22:07:24 浏览量: 1003