跟chatGPT一起复习前端 —— React

192 阅读26分钟

前言

又到一波面试准备的时刻,整理了一波前端相关要点内容,配合chatGPT完成要点内容的整理输出,有纠正错误和需要补充的小伙伴可以在这里留言,及时更新。

对于React 框架的理解(React的特性有哪些)

React 是一个用于构建用户界面的 JavaScript 库。React 的特点有:

  • 声明式设计:React采用声明范式,可以轻松描述应用。
  • 高效:React通过对DOM的模拟,最大限度地减少与DOM的交互。
  • 灵活:React可以与已知的库或框架很好地配合。

React 的优点有:

  • 速度快:在UI渲染过程中,React通过在虚拟DOM中的微操作来实现对实际DOM的局部更新。
  • 跨浏览器兼容:虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的API,甚至在IE8中都是没问题的。

React 的缺点有:

  • 只关注于View层,需要配合其他库使用。
  • 上手难度较高。

为什么提出jsx

JSX 是 React 的一种语法扩展,它可以让我们在 JavaScript 中编写类似于 HTML 的代码,这样就可以更方便地描述 UI。JSX 代码会被编译成纯 JavaScript 代码,然后再由 React 渲染到页面上。

JSX 的出现是为了让开发者更方便地编写组件,因为它可以让我们在 JavaScript 中直接嵌入 HTML 标签,这样就可以更方便地描述 UI。同时,JSX 还支持使用 JavaScript 表达式,这样就可以更方便地处理动态数据。

需要注意的是,JSX 并不是必须的,你完全可以使用纯 JavaScript 来编写 React 组件。但是使用 JSX 可以让你的代码更加简洁易懂,同时也可以提高开发效率。

Babel 插件是如何实现 JSX 到 JS 的编译?

Babel 插件是通过 Babel 的 transform 插件来实现 JSX 到 JS 的编译的。其中,babel-plugin-transform-react-jsx 插件的作用是将 JSX 转换成 React.createElement 方法调用。Babel 的编译流程主要分为三个部分:解析(parse),转换(transform),生成(generate)。其中,转换阶段是通过插件来实现的,因此任何人都可以为 babel 编写自己的转换插件,以支持实现广泛的功能。

对于React虚拟DOM的理解

虚拟DOM是一种编程概念,它是一个虚拟的DOM树,它是由React组件树生成的。React使用虚拟DOM来减少对实际DOM的操作,从而提高性能。当React组件的状态发生变化时,React会重新计算虚拟DOM树,并将其与先前的虚拟DOM树进行比较,以确定哪些部分需要更新。然后,React将仅更新需要更新的部分,而不是整个DOM树。这使得React应用程序更快、更高效。

在React中,虚拟DOM是通过JSX来创建的。JSX是一种JavaScript语法扩展,它允许您在JavaScript代码中编写类似HTML的标记。当您编写JSX时,您实际上正在创建一个JavaScript对象,该对象表示您要在屏幕上呈现的内容。React使用这些对象来构建虚拟DOM树。

VDOM 和 DOM 的区别

DOM 是文档对象模型,是浏览器将 HTML 文档解析成树形结构的方式。虚拟 DOM 是一种编程概念,是指在内存中用 JavaScript 对象模拟 DOM 树的结构,通过对比新旧两个虚拟 DOM 的差异,最终只更新需要更新的部分,从而减少了对真实 DOM 的操作次数,提高了性能。

简单来说,DOM 是浏览器解析 HTML 文档生成的树形结构,而虚拟 DOM 是用 JavaScript 对象模拟的树形结构。虚拟 DOM 可以避免频繁操作真实 DOM,从而提高性能。

VDOM 和 DOM 的优缺点

DOM 的优点是可以直接操作真实的 DOM,但是频繁操作真实 DOM 会影响性能。虚拟 DOM 的优点是可以避免频繁操作真实 DOM,从而提高性能。虚拟 DOM 可以将多次操作合并成一次操作,从而减少了对真实 DOM 的操作次数,提高了性能。

虚拟 DOM 的缺点是需要额外的内存空间来存储虚拟 DOM,而且需要将虚拟 DOM 转换成真实 DOM,这也会消耗一定的性能。

react 的生命周期

React 的生命周期是指在 React 组件运行过程中,组件会自动调用一些特定的函数,这些函数就是 React 生命周期函数。React 生命周期大致上可以分为初始化(Initialization)、挂载(Mounting)、更新(Updating)和卸载(Unmounting)这几个阶段,每个阶段又会分别调用不同的生命周期函数。

具体来说,React 组件的生命周期包括以下函数:

  • constructor()
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount()
  • shouldComponentUpdate()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()
  • componentWillUnmount()

其中,constructor() 是组件的构造函数,用于初始化组件的状态;render() 函数是组件必须实现的函数,用于渲染组件;componentDidMount() 函数是组件挂载后调用的函数,用于获取数据等操作;shouldComponentUpdate() 函数是组件更新前调用的函数,用于判断是否需要更新组件;componentWillUnmount() 函数是组件卸载前调用的函数,用于清理组件。

react的事件机制

React 的事件机制利用了事件委托机制。事件并没有绑定在真实的 DOM 节点上,而是把事件都绑定在结构的最外层 document,使用一个统一的事件监听器。这样做的好处是减少内存消耗和动态绑定事件。

React 上注册的事件最终会绑定在 document 这个 DOM 上,而不是 React 组件对应的 DOM。所有的事件都绑定在 document 上,其他节点没有绑定事件。这样做可以减少内存开销。

函数组件和类组件输出差别(闭包陷阱)

函数组件和类组件的输出差别主要在于语法和生命周期。函数组件是一个纯函数,它接收一个props对象返回一个react元素;而类组件需要去继承React.Component并且创建render函数返回react元素。函数组件没有生命周期和状态state,而类组件有。

另外,函数组件的闭包中捕获的值永远都是确定且安全的,而类组件是通过各种生命周期函数来包装业务逻辑的。

受控组件和非受控组件

在 React 中,组件分为将状态变化交由 React 处理的组件和通过 ref 引用获取的组件两种,前者称为受控组件,后者称为非受控组件。受控组件的状态由 React 组件管理,而非受控组件的状态在组件自身存储,需要的时候通过 ref 查询 DOM 并查找其值。

React如何实现状态自动保存(vue中的keep-alive)

在 Vue 中,我们可以非常便捷地通过 <keep-alive> 标签实现状态的保存,该标签会缓存不活动的组件实例,而不是销毁它们。而在 React 中并没有这个功能,但是有一些第三方库可以实现这个功能。例如 react-activation 和 react-keep-alive 等等。这些库都是通过缓存组件的方式来实现状态自动保存的。

对react hook的理解,解决了什么问题

React Hook 是 React 16.8 的新增特性,它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。官方给出的动机是解决长时间使用和维护 React 过程中常遇到的问题,例如:

  • 难以重用和共享组件中的与状态相关的逻辑。
  • 逻辑复杂的组件变得难以理解。
  • 难以理解的 class。

Hook 解决了 React 用户们直接面对的问题(渲染 props 和高阶组件,以及生命周期方法中的重复逻辑造成的” wrapper 地狱”)和在优化 React 大规模化时候遇到的问题(比如用编译器处理内联组件时的困难)。

React常用的hooks

以下是一些常用的React Hooks:

  • useState:用于在函数组件中添加状态
  • useEffect:用于在函数组件中添加副作用
  • useContext:用于在函数组件中使用上下文
  • useReducer:用于在函数组件中使用Redux
  • useCallback:用于在函数组件中缓存回调
  • useMemo:用于在函数组件中缓存计算结果
  • useRef:用于在函数组件中引用DOM元素

您应该只在组件的顶层调用Hooks,在任何return关键字之前。不应该在循环、条件或嵌套函数中使用Hooks。

useEffect的触发时机

useEffect是React Hooks中的一个函数,它可以让你在函数组件中执行副作用操作,例如数据获取、订阅、手动修改DOM等。useEffect的触发时机有以下几种情况:

  • 组件挂载时
  • 组件更新时
  • 组件卸载时

useEffect的触发时机取决于它的第二个参数,即依赖数组。当依赖数组为空时,useEffect只会在组件挂载和卸载时触发;当依赖数组不为空时,useEffect会在依赖项发生变化时触发。如果依赖项是一个对象或数组,需要注意的是,每次渲染都会生成新的对象或数组,因此需要使用useMemo或useCallback来避免不必要的渲染。

useEffect的第一个函数返回一个函数

useEffect的第一个函数参数可以返回一个函数,这个函数会在组件卸载时执行,用于清理副作用。如果不需要清理副作用,useEffect就不用返回任何值。

useEffect和useLayoutEffect有什么区别

useEffect和useLayoutEffect都是React官方推出的两个hooks,都是用来执行副作用的钩子函数,名字类似,功能相近,唯一不同的就是执行的时机有差异。其中,useEffect会在组件渲染到屏幕上之后执行,而useLayoutEffect会在组件渲染到屏幕上之前执行。如果你需要在组件渲染到屏幕上之前执行一些操作,那么就可以使用useLayoutEffect。如果你需要在组件渲染到屏幕上之后执行一些操作,那么就可以使用useEffect。

需要注意的是,由于useLayoutEffect会在组件渲染到屏幕上之前执行,因此它可能会阻塞浏览器的渲染进程,导致页面卡顿。所以,在大多数情况下,我们应该优先使用useEffect。

hooks使用规则

React Hooks的使用规则如下:

  • Hooks只在顶层调用,不要在循环,条件判断或者嵌套函数中调用钩子。
  • 只在React的函数组件 (function Component)中调用Hooks,在类组件 (class Component)中无法使用。
  • 对于自定义Hooks,使用use开头命名。
  • eslint-plugin-react-hooks该插件可以规范hooks写法。
  • React 靠的是 Hook 调用的顺序来对应state和useState,所以一定要注意。

useMemo、memo、useCallback

useMemo, memo, 和 useCallback 都是 React Hook 中的 API,用于优化性能。其中,useMemo 用于缓存计算结果,避免在每次渲染时都重新计算;useCallback 用于缓存回调函数本身,避免在每次渲染时都重新创建回调函数;而 memo 则是一个高阶组件,用于缓存组件的渲染结果,避免在每次渲染时都重新渲染组件。

这三个 API 的使用场景有所不同。如果你需要缓存一个计算结果,那么可以使用 useMemo;如果你需要缓存一个回调函数本身,那么可以使用 useCallback;如果你需要缓存一个组件的渲染结果,那么可以使用 memo

ref使用场景

React中的ref是一个用于获取组件实例或DOM元素的方法。ref的使用场景包括但不限于以下几种1:

  • 控制一些DOM原生的效果,如输入框的聚焦效果和选中效果等;
  • 触发一些命令式的动画;
  • 集成第三方的DOM库。

super和super(props)的区别

在React中,super()是调用父类的构造函数,而super(props)则是在调用父类的构造函数的同时,将props传递给父类。如果不传递props给super,则子类的props会是Undefined。

react事件绑定方式有哪些

React事件绑定的方式有以下几种12:

  • 最简单的事件绑定:<button onClick={this.showAlert}>show</button>
  • 在render方法中使用bind:<button onClick={this.showAlert.bind(this)}>show</button>
  • 在render方法中使用箭头函数:<button onClick={() => this.showAlert()}>show</button>
  • 在构造函数中使用bind:constructor(props) { super(props); this.showAlert = this.showAlert.bind(this); }

这四种方式的区别主要在于编写方面和性能方面。

react 中组件之间如何通信

React 中组件之间通信的方式有很多种,以下是其中几种常用的方式:

  • 父组件向子组件通信:父组件通过向子组件传递 props,子组件得到 props 后进行相应的处理。
  • 子组件向父组件通信:利用回调函数,可以实现子组件向父组件通信:父组件将一个函数作为 props 传递给子组件,子组件调用该回调函数,便可以向父组件通信。
  • 跨级组件通信:父组件向子组件的子组件通信,向更深层的子组件通信。跨级组件通信可以采用中间组件层层传递 props 的方式。
  • 非嵌套组件间通信:利用二者共同父组件的 context 对象进行通信。

除此之外还有事件订阅的方向进行跨组件通信。

React中key的作用

React中key的作用是:在diff算法中判断元素是最新创建的还是被移动来的,从而减少不必要的diff,也就是为了提高diff同级比较的效率,避免原地复用带来的副作用;key是react用来追踪列表的元素被修改,被添加或者是被删除的标识。

简单来说,key是React用来识别组件,它是一种身份标识,就像每个人有一个身份证来做辨识一样。

如果你在渲染列表时没有为每个列表项指定一个唯一的key值,那么React会发出警告。如果你不指定key值,那么React会默认使用索引作为key值。但是这样做可能会引发一些不确定的bug,所以我们在写循环列表输出时还是建议将key这个属性带上。

react函数组件和类组件的区别

在 React.js 开发中, 函数组件 (function component) 和 类组件 (class component) 的区别如下:

  • 类组件提供了更多的特性 (比如 state),而函数组件则没有。但是,随着 React Hooks 的到来,这个说法也不成立了 (通过hooks,函数组件也可以有 state 和类生命周期回调了)。
  • 类组件可以使用生命周期函数,而函数组件不能。
  • 类组件可以使用 this 关键字来访问自己的属性和方法,而函数组件则不能。
  • 类组件可以使用 refs 来访问子元素,而函数组件则不能。

总的来说,如果你需要使用生命周期函数、refs 或者是需要在组件内部保存一些状态,那么你应该选择类组件。如果你只需要简单地渲染一些内容,那么你应该选择函数组件,但是由于Hooks的出现,更加优先选择函数组件。

react高阶组件以及应用场景

高阶组件是 React 中用于复用组件逻辑的一种高级技巧。它是一种基于 React 的组合特性而形成的设计模式,自身不是 React API 的一部分。高阶组件可以接受一个组件作为参数,并返回一个新的组件。这个新的组件可以包装原来的组件,从而提供了新的功能。

应用场景:需要代码重用时,如果有多个组件都用到了同一段逻辑,就可以把共同的逻辑部分提取出来,利用高阶组件的形式将这段逻辑整合到每一个组件中,从而减少代码的逻辑重复。

react组件间的过度动画如何实现

在 React 中实现过渡动画效果会有很多种选择,如 react-transition-groupreact-motionAnimated,以及原生的 CSS 都能完成切换动画。其中,react-transition-group 是一个常用的库,它提供了一些组件来帮助我们实现过渡动画效果。你可以通过它提供的组件来实现组件间的过渡动画效果。例如,你可以使用 <CSSTransition> 组件来实现基于 CSS 的过渡动画效果。如果你想要更加灵活的过渡动画效果,你可以使用 <Transition> 组件来自定义过渡动画效果。

如果你想要更加复杂的过渡动画效果,你可以使用 react-motion 库。它提供了一些组件和 API 来帮助我们实现更加复杂的过渡动画效果。

如果你想要使用原生的 CSS 来实现过渡动画效果,你可以使用 React 的 style 属性来设置元素的样式。然后,在元素的样式发生变化时,React 会自动地为你处理过渡动画效果。

ReactRouter 组件的理解,常用的react router组件

React Router 是一个基于 React 之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与 URL 的同步。React Router 的核心理念是:一切皆组件。React Router 中有三种类型的组件:路由器组件,路由匹配组件,导航组件。其中,Router 与 Route 一样都是 react 组件 ,它的 history 对象是整个路由系统的核心,它暴露了很多属性和方法在路由系统中使用; Route 的 path 属性表示路由组件所对应的路径,可以是绝对或相对路径,相对路径可继承; Redirect 是一个重定向组件,有 from 和 to 两个属性。

React Router有几种模式,实现原理是什么

React Router有两种模式:HashRouter和BrowserRouter。HashRouter使用URL的hash部分(即#后面的部分)来作为路由地址,而BrowserRouter使用HTML5的history API来实现路由。HashRouter的实现原理是监听window.location.hash的变化,而BrowserRouter则是监听popstate事件。

react render原理,在什么时候触发

React 的渲染过程是将组件转换为 DOM 元素的过程。当组件的状态或属性发生变化时,React 会重新渲染组件并更新 DOM。React 的渲染过程分为两个阶段:Reconciliation 和 Commit。Reconciliation 阶段是 React 更新虚拟 DOM 的阶段,Commit 阶段是 React 将虚拟 DOM 转换为真实 DOM 的阶段。在 Reconciliation 阶段,React 会比较新旧虚拟 DOM 树的差异,找出需要更新的部分。在 Commit 阶段,React 会将需要更新的部分转换为真实 DOM 并插入到页面中。

在 React 中,render() 方法用于在提供的容器参数 container 里渲染一个 React 元素 element。render() 方法返回对该组件的引用(或者针对无状态组件返回 null)。

React 的 render 函数是 React 组件中的一个方法,用于渲染组件的内容。在 React 中,类组件只要执行了 setState 方法,就一定会触发 render 函数执行。函数组件使用 useState 更改状态不一定导致重新 render 组件的 props 改变了,不一定触发 render 函数的执行,但是如果 props 的值来自于父组件或者祖先组件的 state,那么 props 改变也会触发 render 函数的执行。

如何提高组件的渲染效率

React 组件的渲染效率可以通过以下几种方式进行提高:

  1. 避免不必要的重新渲染:React 组件的渲染是根据组件的状态和属性来决定的,当组件的状态或属性发生变化时,React 会重新渲染组件并更新 DOM。因此,避免不必要的重新渲染可以提高组件的渲染效率。可以使用 shouldComponentUpdate() 方法来判断是否需要重新渲染组件。
  2. 使用 PureComponent:PureComponent 是 React 中的一个优化版组件,它会自动判断是否需要重新渲染组件,从而提高组件的渲染效率。
  3. 使用 React.memo():React.memo() 是一个高阶组件,它可以缓存组件的结果,从而避免不必要的重新渲染。
  4. 使用 key 属性:在使用列表渲染时,为每个列表项添加唯一的 key 属性可以帮助 React 更好地识别每个列表项,从而避免不必要的重新渲染。
  5. 使用 shouldComponentUpdate() 方法:shouldComponentUpdate() 方法可以帮助我们判断是否需要重新渲染组件。
  6. 使用 React Profiler:React Profiler 可以帮助我们分析应用程序中每个组件的性能瓶颈,并提供优化建议。
  7. 使用 React.lazy() 和 Suspense:React.lazy() 和 Suspense 可以帮助我们实现代码分割和懒加载,从而提高应用程序的性能。

react diff

React 的每次更新,都会将新的 ReactElement 内容与旧的 fiber 树作对比,比较出它们的差异后,构建新的 fiber 树,将差异点放入更新队列之中,从而对真实 dom 进行 render。这个算法叫做 diff 算法。

diff 算法是 Virtual DOM 产生的一个概念,用来计算出 Virtual DOM 中真正变化的部分,并只针对该部分进行原生 DOM 操作,而非重新渲染整个页面,从而提高了页面渲染效率。

React 中使用「三个层级策略」对 diff 算法进行了优化。

  • 第一层级:同层级比较。如果两个节点类型不同,则直接替换。
  • 第二层级:同父节点比较。如果两个节点类型相同,则继续比较其子节点。
  • 第三层级:跨级比较。如果两个节点类型相同,则继续比较其子节点。

这样做可以大大减少 diff 算法的计算量,提高页面渲染效率。

JSX转换成真实DOM的过程

在React中,JSX会被转换成虚拟DOM,然后再通过ReactDOM.render()方法渲染成真实DOM。虚拟DOM会通过ReactDOM.render()进行渲染成真实DOM。首次渲染的时候,容器中的所有DOM节点都会被替换掉,以后的更新就会使用React中的diff算法来进行比较。如果传递了callback回调函数,就会在渲染完成的时候再进行回调。

在React源码中,虚拟DOM转化成真实DOM整体流程如下图所示:使用React.createElement或JSX编写React组件,实际上所有的JSX代码最后都会转换成React.createElement(…),Babel帮助我们完成了这个转换的过程。createElement函数对key和ref等特殊的props进行处理,并获取defaultProps对默认props进行赋值,并且对传入的孩子进行处理。最后返回一个对象,这个对象就是虚拟DOM。

react 性能优化的手段

React 性能优化的手段有很多,其中一些包括:

  • 使用 shouldComponentUpdate() 方法来避免重复渲染
  • 使用 Immutable.js 来减少渲染次数
  • 使用 React.PureComponent 来避免不必要的渲染
  • 使用 React.memo() 来避免不必要的渲染
  • 使用 React.lazy() 和 Suspense 来延迟加载组件
  • 使用 Webpack 的 Code Splitting 来分割代码
  • 使用 React Profiler 来检测性能问题
  • 避免在 render() 方法中使用 bind() 方法
  • 避免在 render() 方法中使用箭头函数
  • 避免在 render() 方法中使用内联样式

fiber架构

React Fiber 架构是 React 核心算法的重新实现,它的主要特点是渐进式渲染,能够将渲染工作分割成块,并将其分散到多个帧。Fiber 架构就是为了支持“可中断渲染”而创建的,它的目标是使 React 能够在不阻塞浏览器主线程的情况下进行渲染。

从架构角度来看,Fiber 是对 React 核心算法(即调和过程)的重写。从编码角度来看,Fiber 是 React 内部所定义的一种数据结构,它是 Fiber 树结构的节点单位,也就是 React 16 新架构下的虚拟 DOM。

在React项目中如何捕获错误

在React项目中,你可以使用错误边界来捕获错误。错误边界是一种React组件,它可以捕获发生在其子组件树任何位置的JavaScript错误,并打印这些错误,同时展示降级UI,而不会渲染那些发生崩溃的子组件树。React16引入了错误边界的新概念,以解决出现的错误导致整个应用崩溃的问题。

redux

Redux是一个JavaScript状态管理库,它可以帮助你管理React应用程序中的状态。Redux的核心思想是将应用程序的状态存储在一个单一的地方,称为store。组件可以从store中获取数据,也可以将数据写入store。当store中的数据发生变化时,所有订阅store的组件都会自动更新。这种方式使得应用程序的状态变得可预测和可控,同时也使得代码更容易维护和测试。

Redux的工作原理是将整个应用程序的状态存储在一个地方,称为store。store是一个JavaScript对象,它包含了应用程序的所有状态。当组件想要读取或修改状态时,它们必须通过dispatch一个action来告诉Redux要执行什么操作。然后,Redux会根据这个action来更新store中的状态,并通知所有订阅store的组件进行更新。

mobx

MobX是一个用于管理前端状态变更的JavaScript库。它通过透明的函数响应式编程(TFRP)使得状态管理变得简单和可扩展。MobX背后的哲学很简单:任何源自应用状态的东西都应该自动地获得。MobX是一个简单、可扩展的状态管理,当应用状态更新时,任何源自应用状态的东西都将自动地获得。React和MobX是一对强力组合,React通过组件化UI使得构建UI变得简单,而MobX通过透明的函数响应式编程使得状态管理变得简单和可扩展。

使用MobX,你可以定义在相关数据发生变化时自动更新的值。通过@computed装饰器或者利用(extend)Observable时调用的getter/setter函数来进行使用。你也可以使用decorate来替代@语法。

MobX是一个功能强大,上手非常容易的状态管理工具。它是一个简单、可扩展的状态管理,当应用状态更新时,任何源自应用状态的东西都将自动地获得。MobX和React是一对强力组合,React通过组件化UI使得构建UI变得简单,而MobX通过透明的函数响应式编程使得状态管理变得简单和可扩展。

Mobx和Redux有什么区别?

Mobx和Redux都是状态管理工具,但是它们有一些不同之处。Redux是一个使用叫做“action”的事件来管理和更新应用状态的模式和工具库,它以集中式Store(centralized store)的方式对整个应用中使用的状态进行集中管理。而Mobx是一个简单、可扩展的状态管理,当应用状态更新时,任何源自应用状态的东西都将自动地获得。Mobx和React是一对强力组合,React通过组件化UI使得构建UI变得简单,而MobX通过透明的函数响应式编程使得状态管理变得简单和可扩展。

ReactQuery

React Query是一个React数据获取库,它可以管理任何形式的异步状态——只要它得到一个Promise。使用React Query,你可以很方便地获取、同步、更新和缓存你的远程数据。

React Query是一个React Hooks的库,它可以帮助你管理服务端请求的状态。React Query的优势包括:

  • 缓存数据,避免重复请求
  • 知道数据何时“过时”,并在后台更新“过时”的数据
  • 分页、延迟加载等性能优化
  • 结构化共享并存储查询结果

React18有哪些更新?

React 18是React的最新版本,于2022年3月发布。React 18的主要更新是引入了新的并发模式,这使得React应用程序可以更好地利用现代浏览器的多核CPU。此外,React 18还包括一些新的API和功能

  • 新的并发模式
  • 新的useId、useSyncExternalStore和useDeferredValue钩子
  • 新的startTransition API
  • Suspense List
  • createRoot API替换render API

React和Vue框架的区别

React和Vue都是流行的JavaScript框架,它们都遵循组件化思想,将页面分成一些细块,也就是组件,组件之间组合嵌套就形成最后的网页界面。以下是React和Vue的一些区别:

  • 框架本质不同:Vue本质是MVVM框架,是由MVC发展来的;React是前端组件框架,是由后端组件演化而来的。
  • 数据流不同:Vue实现双向绑定,React一直不支持双向绑定,提倡的是单向数据流;
  • 监听数据变化的实现原理不同:Vue通过getter,setter以及一些函数的劫持,能精确知道数据的变化。React是通过比较引用方式(diff)进行的,当应用的状态改变时,全部组件都会重新渲染。
  • 组件写法差异:React推荐的做法是JSX + inline style, 也就是把 HTML 和 CSS 全都写进 JavaScript 中;Vue 推荐的做法是 template 的单文件组件格式,即 html,css,JS 写在同一个文件(vue也支持JSX写法)
  • 渲染过程不同:Vue可以更快地计算出Virtual DOM的差异,这是由于它在渲染过程中,会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。React在应用的状态被改变时,全部子组件都会重新渲染。通过shouldComponentUpdate这个生命周期方法可以进行控制。
  • 在state上的不同:React中,state对象需要用setState方法更新状态;在Vue中,state对象不是必须的,数据由data属性在vue对象中管理。