**目录** 前端基础高频面试题之-- React 篇 1、什么是React? 2、React有什么特点? 3、列出React的一些主要优点。 4、React有哪些限制? 5、什么是JSX? 6、为什么浏览器无法读取JSX? 7、React中的组件是什么? 8、怎样解释 React 中 render() 的目的。 9、什么是 Props? 10、React中的状态是什么?它是如何使用的? 11、…


本文汇总了前端面试中经常问到的 React 基础高频面试题,面试常问的基本都在这里。
用于构建用户界面的 JavaScript 库,提供了 UI 层面的解决方案,遵循组件设计模式、声明式编程范式和函数式编程概念,以使前端应用程序更高效,使用虚拟DOM来有效地操作DOM,遵循从高阶组件到低阶组件的单向数据流,帮助我们将界面成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,构成整体页面.
JSX 是JavaScript XML 的简写。是 React 使用的一种文件,它利用 JavaScript 的表现力和类似 HTML 的模板语法。这使得 HTML 文件非常容易理解。此文件能使应用非常可靠,并能够提高其性能(说白了就是可以在 js 中写 html)。
浏览器只能处理 JavaScript 对象,而不能读取常规 JavaScript 对象中的 JSX。所以为了使浏览器能够读取 JSX,首先,需要用像 Babel 这样的 JSX 转换器将 JSX 文件转换为 JavaScript 对象,然后再将其传给浏览器。
组件是React应用的构建块。它们是独立且可重用的代码片段,用于定义UI的一部分。组件可以是类组件或函数组件,并且可以维护自己的状态和生命周期。
每个React组件强制要求必须有一个 render()。它返回一个 React 元素,是原生 DOM 组件的表示。如果需要渲染多个 HTML 元素,则必须将它们组合在一个封闭标记内,例如 <form>、<group>、<div> 等。此函数必须保持纯净,即必须每次调用时都返回相同的结果。
Props 是 React 中属性的简写。它们是只读组件,必须保持纯,即不可变。它们总是在整个应用中从父组件传递到子组件。子组件永远不能将 prop 送回父组件。这有助于维护单向数据流,通常用于呈现动态生成的数据。
状态是 React 组件的核心,是数据的来源,必须尽可能简单。基本上状态是确定组件呈现和行为的对象。与props 不同,它们是可变的,并创建动态和交互式组件。可以通过 this.state() 访问它们。
箭头函数(=>)是用于编写函数表达式的简短语法。这些函数允许正确绑定组件的上下文,因为在 ES6 中默认下不能使用自动绑定。使用高阶函数时,箭头函数非常有用。
好处:
高阶组件是重用组件逻辑的高级方法,是一种源于 React 的组件模式。HOC 是自定义组件,在它之内包含另一个组件。它们可以接受子组件提供的任何动态,但不会修改或复制其输入组件中的任何行为。你可以认为 HOC 是'纯(Pure)'组件。
纯(Pure) 组件是可以编写的最简单、最快的组件。它们可以替换任何只有 render() 的组件。这些组件增强了代码的简单性和应用的性能。
##15、React 中 key 的重要性是什么?key 用于识别唯一的 Virtual DOM 元素及其驱动 UI 的相应数据。它们通过回收 DOM 中当前所有的元素来帮助 React 优化渲染。这些 key 必须是唯一的数字或字符串,列表元素需要一个唯一的key来帮助React识别哪些项已经改变、添加或删除。这提高了渲染列表的性能,尤其是在进行列表项的重新排序或操作时。
React 路由是一个构建在 React 之上的强大的路由库,它有助于向应用程序添加新的屏幕和流。这使 URL 与网页上显示的数据保持同步。它负责维护标准化的结构和行为,并用于开发单页 Web 应用。React 路由有一个简单的API。
因为解构赋值的原因:
React 16.6 之后,React 提供了 React.lazy 方法来支持组件的懒加载。配合 webpack 的 code-splitting 特性,可以实现按需加载。
import React, { Suspense } from 'react'; const OtherComponent = React.lazy(() => import('./OtherComponent')); function MyComponent() { return ( <div> <Suspense fallback={<div>Loading...</div>}> <OtherComponent /> </Suspense> </div> ); }
0、设计理念
React: 更倾向于函数式编程思想,推崇组件的不可变性和单向数据流。Vue: 结合了响应式编程和模板系统,致力于简化开发过程。
1、组件化方式不同React 组件包含状态和行为,所有组件共享一个状态树Vue 每个组件都有自己的状态和行为,并且可以很容易将数据和行为绑定在一起
2、数据驱动方式不同React 主要采用单向数据流,组件状态通过setState方法更新Vue 支持双向数据绑定(使用v-model指令),适合于简化表单输入等场景。
3、模板语法不同React 使用JSX(JavaScript XML),将标记语言与JavaScript逻辑混写。Vue 使用基于HTML的模板语法,允许开发者使用纯HTML、CSS和JavaScript,支持指令
4、生命周期不同React 生命周期:初始化、更新、卸载Vue 生命周期:创建、挂载、更新、销毁
5、状态管理方式不同React 状态管理通常通过使用Context API或引入如Redux、MobX的库来实现。Vue 提供了Vuex作为官方的状态管理解决方案。
6、性能优化方式不同React 性能优化:React.memo、shouldComponentUpdateVue 性能优化:keep-alive、v-if
7、响应式系统React: 通过setState和useState等API显式地触发UI更新。Vue: 通过其响应式系统自动追踪依赖并在数据变化时更新视图。
8、类型支持React: 原生支持JavaScript,但可以很好地与TypeScript结合。Vue: Vue 3提供了更好的TypeScript支持。
父组件 => 子组件:
子组件 => 父组件:
兄弟组件之间:
不相关的组件之间:
useReducer 是 React Hooks 中的一个函数,用于管理和更新组件的状态。它可以被视为 useState 的一种替代方案,适用于处理更复杂的状态逻辑。相比于 useState,useReducer 在处理复杂状态逻辑时更有优势,因为它允许我们将状态更新的逻辑封装在 reducer 函数中,并根据不同的动作类型执行相应的逻辑。这样可以使代码更具可读性和可维护性,并且更容易进行状态追踪和调试。
1、语法不同、设计思想不同
函数式组件是函数式编程思想,而类组件是面向对象编程思想。面向对象编程将属性和方法封装起来,屏蔽很多细节,不利于测试。
2、生命周期、状态变量
3、复用性
注意:react 18 之前
setState的'异步'并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形式了所谓的'异步',当然可以通过第二个参数 setState(partialState, callback) 中的callback拿到更新后的结果。
react 18 之后setState都会表现为异步(即批处理)。
1、node server 接收客户端请求,得到当前的请求 url 路径,然后在已有的路由表内查找到对应的组件,拿到需要请求的数据,将数据作为 props、context或者store 形式传入组件
2、然后基于 react 内置的服务端渲染方法 renderToString() 把组件渲染为 html 字符串在把最终的 html 进行输出前需要将数据注入到浏览器端
3、浏览器开始进行渲染和节点对比,然后执行完成组件内事件绑定和一些交互,浏览器重用了服务端输出的 html 节点,整个流程结束
状态钩子 (useState): 用于定义组件的 State,类似类定义中 this.state 的功能useReducer:用于管理复杂状态逻辑的替代方案,类似于 Redux 的 reducer。生命周期钩子 (useEffect): 类定义中有许多生命周期函数,而在 React Hooks 中也提供了一个相应的函数 (useEffect),这里可以看做- componentDidMount、componentDidUpdate和componentWillUnmount的结合。useLayoutEffect:与 useEffect 类似,但在浏览器完成绘制之前同步执行。useContext: 获取 context 对象,用于在组件树中获取和使用共享的上下文。useCallback: 缓存回调函数,避免传入的回调每次都是新的函数实例而导致依赖组件重新渲染,具有性能优化的效果;useMemo: 用于缓存传入的 props,避免依赖的组件每次都重新渲染;useRef: 获取组件的真实节点;用于在函数组件之间保存可变的值,并且不会引发重新渲染。useImperativeHandle:用于自定义暴露给父组件的实例值或方法。useDebugValue:用于在开发者工具中显示自定义的钩子相关标签。useEffect 在 React 的渲染过程中是被异步调用的,用于绝大多数场景;useLayoutEffect 会在所有的 DOM 变更之后同步调用,主要用于处理 DOM 操作、调整样式、避免页面闪烁等问题。也正因为是同步处理,所以需要避免在 useLayoutEffect 做计算量较大的耗时任务从而造成阻塞。
useEffect 是按照顺序执行代码的,改变屏幕像素之后执行(先渲染,后改变DOM),当改变屏幕内容时可能会产生闪烁;useLayoutEffect 是改变屏幕像素之前就执行了(会推迟页面显示的事件,先改变DOM后渲染),不会产生闪烁。useLayoutEffect总是比useEffect先执行。
state是组件内部的状态,可以被组件自身管理和更改。props(属性)是从父组件传递给子组件的数据,子组件不能修改接收到的props(单向数据流)。相同点:
区别:
虚拟DOM是内存中的DOM表示。React使用虚拟DOM来优化DOM的更新过程。它通过比较新旧虚拟DOM的差异,并仅更新实际DOM中改变的部分,提高应用性能。
componentWillMount:在渲染之前执行,用于根组件中的 App 级配置。componentDidMount:在第一次渲染之后执行可以在这里做AJAX请求,DOM 的操作或状态更新以及设置事件监听器。componentWillReceiveProps:在初始代render的时候不会执行,它会在组件接受到新的状态(Props)时被触发,一般用于业组件状态更新时子组件的重新渲染。shouldComponentUpdate:确定是否更新组件。默认情况下,它返回true。如果确定在 state 或props 更新后组件不需要在重新渲染,则可以返回false,这是一个提高性能的方法。componentWillUpdate:在shouldComponentUpdate返回 true 确定要更新组件之前执行。componentDidUpdate:它主要用于更新DOM以响应props或state更改。componentWillUnmount:它用于取消任何的网络请求,或删除与组件关联的所有事件监听器。Hooks 通常支持提取和重用跨多个组件通用的有状态逻辑,而无需承担高阶组件或渲染 props 的负担。
Hooks 可以轻松地操作函数组件的状态,而不需要将它们转换为类组件。
避免使用生命周期方法。
先执行子组件再执行父组件。react保证了每次运行useffect的同时,DOM都已经更新完毕。有一些场景,需要父组件的执行顺序在子组件前面,可以考虑一下使用useLayoutEffect
受控组件是React控制的组件,input等表单输入框值不存在于 DOM 中,而是以我们的组件状态存在。每当我们想要更新值时,我们就像以前一样调用setState。
不受控制组件是您的表单数据由 DOM 处理,而不是React 组件,Refs 用于获取其当前值;
Redux 是 React 的第三方状态管理库,创建于上下文API存在之前。它基于一个称为存储的状态容器的概念,组件可以从该容器中作为 props 接收数据。更新存储区的唯一方法是向存储区发送一个操作,该操作被传递到一个reducer中。reducer接收操作和当前状态,并返回一个新状态,触发订阅的组件重新渲染。
React Keep Alive 提供了 ,你必须把 放在 Provider 里面,并且每个 组件都必须拥有一个唯一的 key
React 有三种构建组件的方式
虚拟dom相当于在js和真实dom中间加了一个缓存,利用dom diff算法避免了没有必要的dom操作,从而提高性能。
useCallback 和 useMemo 可以用来缓存函数和变量,提高性能,减少资源浪费。但并不是所有的函数和变量都需要用这两者来实现,他也有对应的使用场景。
我们知道 useCallback 可以缓存函数体,在依赖项没有变化时,前后两次渲染时,使用的函数体是一样的。它的使用场景是:
函数作为其他 hook 的依赖项时(如在 useEffect()中);函数作为 React.memo()(或 shouldComponentUpdate )中的组件的 props;主要是为了避免重新生成的函数,会导致其他 hook 或组件的不必要刷新。
useMemo 用来缓存函数执行的结果。如每次渲染时都要执行一段很复杂的运算,或者一个变量需要依赖另一个变量的运算结果,就都可以使用 useMemo()。
因为在 JavaScript 里 class 是一个关键字,用来定义类。所以在 JSX 里不能再用 class 来表示 HTML 元素的类名了,就用 className 来代替,这样就不会和 JavaScript 的关键字冲突了。
React DiffReact 的 Diff 算法主要是基于两个假设:不同类型的元素会产生不同的树;开发人员可以通过设置key属性来告知 React 哪些元素在不同的渲染之间是稳定的。在对比时,React 会对新旧虚拟 DOM 树进行深度优先遍历,分层比较节点,当发现节点类型不同时,直接替换整个子树,当节点类型相同且有key时,会进行更细致的比较和更新。
Vue DiffVue 的 Diff 算法在比较节点时,同样会优先判断节点类型是否相同。在处理列表时也依赖key属性。不过 Vue 的 Diff 算法在某些细节上与 React 有所不同,例如在静态节点和动态节点的处理上,Vue 会对静态节点进行优化,尽量减少对静态节点的重复比较。
react的合成事件,屏蔽了浏览器自带的事件, 解决了浏览器的不兼容,
将事件绑定在document上,按照冒泡或者捕获的路径去收集真正的事件处理函数,在此过程中会先处理原生事件,然后当冒泡到document对象后 普通事件 是绑定在真实dom上
在 React 类组件中,ajax 请求通常放在 componentDidMount 生命周期方法中。因为这个时候组件已经挂载到 DOM 上,可以进行数据的获取操作,并且不会引起额外的渲染。
在 React Hooks 中,ajax 请求通常放在 useEffect hooks 中。
React Hooks在使用时注意事项:
原因:
React实现路由拦截的基本思路还是利用Route的render函数,通过判断拦截条件来实现不同的组件的跳转,从而实现拦截
Portal提供了一种将子节点渲染到存在于父组件以外的DOM节点的优秀方案。
例如:一个Portal的典型用例是当父组件有overflow:hidden或z-index样式时,需要子组件能够在视觉上'跳出'其容器。例如:对话框、悬浮卡以及提示框
·······END·······
喜欢的话可以点个赞关注博主哦!!!

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online