[React] 2023年最新面试题

news2024/11/20 18:38:19

[React] 2023年最新面试题

      • 1. class 组件与函数组件的区别
      • 2. react 18 新特性有那些?
        • 新增 createRoot API
        • 自动批处理
        • 过渡更新
        • 新的Hook
      • 3. redux 和 react-redux 的区别
      • 4. redux 中间件的原理
      • 5. setState 发生了什么 ,render 函数做了什么
      • 6. 虚拟DOM, Fiber
        • 虚拟DOM
        • Fiber
      • 7. useEffect 与 useLayoutEffect 的区别? 同步异步
      • 8. useCallback 和 useMemo的区别
      • 9. Webpack 打包原理

1. class 组件与函数组件的区别

  1. 语法不同

类组件: 使用 ES6 的类语法定义组件。具有 render 方法,并在类组件中使用 this 来引用组件实例。

函数组件: 使用函数定义组件,通常是无状态的。在 React 16.8 之后,可以使用 Hook 来在函数组件中使用状态和其他 React 特性。

  1. 状态的管理不同

类组件: 使用 this.state 和 this.setState 来管理组件的状态。

函数组件: 使用 useState Hook 来在函数组件中添加状态。

  1. 声明周期方法不同

类组件: 有一系列生命周期方法,如 componentDidMount、componentDidUpdate、componentWillUnmount 等,用于处理组件的生命周期事件。

函数组件: 使用 useEffect Hook 来处理函数组件的生命周期事件

const MyFunctionComponent = () => {
  useEffect(() => {
    // 在组件挂载后和更新后执行
    return () => {
      // 在组件卸载前执行
    };
  }, 
  [] // 第二个参数来控制何时运行副作用函数
);
  1. 复杂性:

class 组件语法相对冗长,可能导致较多样板代码。
生命周期方法分散在不同生命周期阶段。

函数组件语法更简洁,减少样板代码。
生命周期相关逻辑集中在 useEffect 中,提高可读性。

  1. 可读性和维护性:

函数组件使代码更易读、易写。
更好地符合 React 社区的最新实践和推荐。

总的来说,函数组件和 Hook 的方式更加推荐,特别是在新项目中。它们使得 React 组件更易于理解、编写和维护,同时提供了更灵活的状态管理和生命周期处理机制。类组件仍然存在,可能在老项目中或特殊场景中使用。

2. react 18 新特性有那些?

新增 createRoot API

在这里插入图片描述

自动批处理

React 18 通过默认做更多批量处理来增加开箱即用性能提升。批量处理指的是 React 为了提高性能将多个 state 更新分组到一个单独的重渲染。
如果仍然希望setState之后立即重新渲染,只需要使用flushSync包裹

function handleClick() {
	// React 18 之前的版本
	(/*...*/).then(() => {
		setCount(c => c + 1); // 立刻重新渲染
		setShow(show => !show); // 立刻重新渲染
	});
}

function handleClick() {
	// React 18
	fecth(/*...*/).then(() => {
		ReactDOM.flushSync(() => {
			setCount(c => c + 1); // 立刻重新渲染
			setFlag(f => !f);
		})
	})
}

过渡更新

用于并发渲染的并发新特性,开发者希望能够在Web Platform引入并发渲染,来实现多个渲染任务的并行渲染,其中Suspense就是基于此诞生的。

React18支持并发特性的三个API

  • startTransition() 在屏幕内容之间进行导航,而不会阻塞用户输入
  • useDeferredValue() 节流处理开销巨大的重新渲染
  • useTransition() startTransition的 hooks钩子
import { startTransition } from 'react';

// 紧急更新
setInputValue(input)

// 标记回调函数内的更新为 非紧急更新
startTransition(() => {
	setSearchQuery(input)
})

这个hook适用于设置延迟值

function Page() {
	const [filters, mergeFilter] = useMergeState(defaultFilters);
	const deferedFilters = React.useDeferredValue(filters);
	
	return (
		<>
			<Filters filters={filters} />
			<List filters={deferedFilters}>
		</>
	)
}

useDeferredValue() 会将List组件的渲染变得更加平滑,深层次看来是 defered value 引起的渲染会被标记为不紧急渲染,会被filters引起的渲染进行抢占,进而达到用户快速输入搜索等场景下页面抖动或卡顿问题。

新的Hook
  • useId 用于生成在客户端和服务端两侧都独一无二的 id
  • useTransition 将一些状态更新标记为过渡更新
  • useDeferredValue 允许推迟渲染树的非紧急更新,类似防抖
  • useSyncExternalStore 允许使用第三方状态管理来支持并发模式,并且能通过对 store 进行强制更新实现数据同步。
  • useInsertionEffect 允许 CSS-in-JS 库解决在渲染中注入样式的性能问题。

3. redux 和 react-redux 的区别

react-redux 是一个用于在 React 应用中管理状态(state)的库,它是基于 Redux 的 React 绑定库。Redux 是一种用于管理 JavaScript 应用程序状态的可预测状态容器,而 react-redux 则简化了在 React 应用中使用 Redux 的过程。

4. redux 中间件的原理

Redux 中间件是一种在 action 被发起和 reducer 处理这个 action 之间进行操作的机制。中间件允许你在 Redux 应用中的 dispatch 过程中拦截、检查、或者修改 action 和 state。Redux 中间件的原理涉及到 Redux 的 dispatch 过程、函数式编程的概念,以及中间件的链式调用。

Redux 的基本 dispatch 过程如下:

  1. 应用中的组件通过调用 store.dispatch(action) 来分发 action。

  2. dispatch 被传递给中间件链。中间件链是在创建 store 时通过 applyMiddleware 函数添加的。

  3. 中间件对 action 进行处理,可以取消、修改、或者发起其他 action。

  4. action 最终到达 reducer,reducer 根据 action 的类型进行相应的 state 更新。

  5. state 更新后,通知所有订阅的组件进行重新渲染。

Redux 中间件的原理主要体现在中间件链的设计和执行过程上:

  1. 中间件链的设计: 中间件被组织成一个链表形式,每个中间件都有机会处理 action。这个链表是通过 applyMiddleware 函数创建的。

  2. dispatch 的增强: 中间件提供了一种方式,使得每个 action 发起的时候都可以执行一些额外的逻辑。中间件通过封装 dispatch 函数,并将其传递给链中的下一个中间件。

  3. next 函数的传递: 在中间件链中,每个中间件都接收到一个 next 函数,它代表链中的下一个中间件。中间件可以选择调用 next(action) 来将 action 传递给下一个中间件,也可以选择不调用,中止链的执行。

  4. 异步处理: 由于中间件可以获取 dispatch 函数和 getState 函数,因此它们可以进行异步操作。例如,Redux Thunk 中间件就允许 action 创建函数返回一个函数而不仅仅是一个普通的 action 对象,这个函数可以在异步操作完成后再 dispatch。

整体来说,Redux 中间件的原理是通过改变 dispatch 函数的行为,使其能够在 action 到达 reducer 之前经过一系列的处理。这种机制使得 Redux 的功能能够被灵活地扩展和定制,例如通过中间件实现异步操作、日志记录、时间旅行调试等功能。

5. setState 发生了什么 ,render 函数做了什么

  1. 接受新的状态: setState可以接受一个新的状态对象或一个函数,该函数返回新的状态。这个状态可以包含要更新的部分或全部组件状态。
  2. 将新的状态合并到当前状态: React会将新状态与当前状态进行合并。这是因为setState可能是异步的,React可能会在后台批量处理多个setState调用。
  3. 触发组件更新流程: 一旦新状态被合并,React会触发组件的更新流程。
  1. 构建虚拟DOM: 当组件被更新时,React首先调用render函数。render函数负责返回一个虚拟DOM(Virtual DOM)树,描述了组件在更新后应该如何呈现。
  2. 对比虚拟DOM和上一次渲染的虚拟DOM: React使用虚拟DOM来提高性能。在render函数返回新的虚拟DOM后,React会将它与上一次渲染的虚拟DOM进行比较,找出实际发生变化的部分。
  3. 计算更新的部分: React会计算出需要进行实际DOM更新的部分,以最小化对实际DOM的操作。
  4. 应用更新: 最后,React将计算出的更新应用到实际DOM上,只更新发生变化的部分,以提高性能。

setState触发了React的更新流程,而render函数则负责描述组件在更新后的状态应该如何呈现,并最终将这个描述应用到实际的DOM上。 React通过使用虚拟DOM和差异算法,尽可能高效地更新实际DOM,以提高性能和用户体验。

6. 虚拟DOM, Fiber

虚拟DOM

虚拟DOM是React的一种概念,它是在内存中维护的一份虚拟的DOM树。当组件的状态发生变化时,React首先在虚拟DOM上进行操作,而不是直接操作实际的DOM。这个虚拟DOM是一个轻量级的 JavaScript 对象树,它映射了真实DOM的结构。

虚拟DOM的工作流程如下:

组件状态更新: 当组件的状态发生变化时,React会创建一个新的虚拟DOM树。

虚拟DOM对比: 新的虚拟DOM树与先前的虚拟DOM树进行比较,找出发生变化的部分。

差异计算: React使用差异算法来计算需要进行更新的最小操作集。

实际DOM更新: 最终,React将计算出的变化应用到实际的DOM上,实现页面的更新。

通过使用虚拟DOM,React可以最小化直接操作实际DOM的次数,从而提高性能。这是因为直接DOM操作通常是昂贵的,而虚拟DOM的比较和计算过程是在内存中进行的,相对来说更快。

Fiber

Fiber是React 16 中引入的一种新的协调引擎,用于更灵活地控制React的渲染过程。在React 16之前,React的渲染过程是递归的,当组件层次很深时,可能导致浏览器阻塞。
Fiber的目标是实现增量式渲染,使React能够在多个帧中分割渲染工作,防止阻塞主线程。Fiber架构引入了一种新的数据结构,可以更灵活地中断、终止或恢复渲染过程,以适应不同的优先级和交互场景。

要点包括:

可中断的渲染: Fiber允许React在执行过程中中断渲染,执行其他高优先级的任务,然后返回并继续渲染。这有助于提高应用的响应性。

优先级调度: Fiber引入了任务调度器,可以根据任务的优先级动态调整渲染的顺序,确保高优先级任务优先完成。

总的来说,虚拟DOM和Fiber是React中两个关键的技术,它们共同为React提供了高效的渲染和更新机制,提高了应用的性能和用户体验。

7. useEffect 与 useLayoutEffect 的区别? 同步异步

useEffect:

  1. 异步执行: useEffect 中的回调函数是异步执行的。这意味着它不会阻塞浏览器渲染,而是会在浏览器完成渲染后执行。因此,它对页面的布局和绘制不会产生直接影响。
  2. 执行时机: useEffect 的效果函数会在浏览器完成渲染后才会被调用。
useEffect(() => {
  // 异步执行的副作用
  console.log('useEffect callback');
}, [/* dependencies */]);

useLayoutEffect

  1. 同步执行: useLayoutEffect 中的回调函数是同步执行的。它会在浏览器布局完成、但在浏览器绘制之前立即执行。这可能会导致一些阻塞,因此应该谨慎使用,以避免对性能产生不利影响。
  1. 执行时机: useLayoutEffect 的效果函数会在浏览器完成布局、但在浏览器绘制之前立即被调用。

如何选择

如果你的副作用不需要同步执行,并且不影响布局,那么使用 useEffect 是更安全的选择,因为它不会导致阻塞。

如果你的副作用依赖于 DOM 的布局信息,并且需要在浏览器绘制之前立即执行,那么 useLayoutEffect 可能更适合。

大多数情况下,优先选择使用 useEffect,因为它更不容易导致性能问题。 useLayoutEffect 应该在确实需要在布局阶段同步执行的情况下使用。

8. useCallback 和 useMemo的区别

useCallbackuseMemo 都是 React 中用于性能优化的 Hook,它们的目标是避免不必要的计算和渲染。尽管它们在使用上有相似之处,但它们的主要区别在于它们的应用场景返回值的类型

useCallback 用于缓存回调函数,以避免在每次渲染时创建新的回调。它的语法如下:

const memoizedCallback = useCallback(
  () => {
    // 回调函数
  },
  [/* 依赖项数组 */]
);

应用场景: 主要用于防止回调函数在每次渲染时都被重新创建,特别是在传递给子组件时,可以避免不必要的子组件重新渲染。

返回值: 返回一个 memoized(记忆的)版本的回调函数

useMemo 用于缓存计算结果,以避免在每次渲染时重新计算。它的语法如下:

const memoizedValue = useMemo(
  () => {
    // 计算结果
    return computeExpensiveValue(a, b);
  },
  [a, b]
);

应用场景: 主要用于优化计算昂贵的值,确保只在相关依赖项变化时进行重新计算。

返回值: 返回一个 memoized(记忆的)版本的计算结果

区别

返回类型: useCallback 返回一个 memoized 的回调函数,而 useMemo 返回一个 memoized 的计算结果。

主要应用场景: useCallback 主要用于缓存回调函数,而 useMemo 主要用于缓存计算结果。

总的来说,useCallback 用于缓存回调函数,而 useMemo 用于缓存计算结果。选择使用哪个取决于你的具体需求。如果你需要缓存一个回调函数以避免不必要的重新渲染,使用 useCallback。如果你需要缓存计算结果以提高性能,使用 useMemo。在一些情况下,你可能需要同时使用这两个 Hook。

9. Webpack 打包原理

Webpack 是一个现代的 JavaScript 应用程序静态模块打包工具。它的打包原理涉及以下关键概念:

入口(Entry): Webpack 从一个或多个入口点开始,根据入口点的依赖关系,递归地构建一个依赖图。

依赖图(Dependency Graph): Webpack 分析入口文件及其所有直接或间接依赖的文件,形成一个依赖图。每个模块都可以是一个文件,也可以是一个通过加载器(Loaders)处理的文件。

加载器(Loaders): 加载器是用于对模块进行转换的工具,它允许你在 import 模块时预处理文件。例如,可以使用 Babel 加载器将 ES6 代码转换为 ES5。

插件(Plugins): 插件用于执行各种任务,例如优化、压缩、拷贝文件等。插件可以在整个构建过程中执行各种任务,包括对生成的 bundle 进行优化和处理。

输出(Output): Webpack 根据依赖图生成一个或多个输出文件,这些文件包含了打包后的代码。输出文件的生成位置和文件名可以通过配置进行指定。

模块(Modules): 在 Webpack 中,一切皆模块。每个文件都被视为一个模块,并且可以包含 JavaScript、CSS、图片等各种类型的资源。

Webpack 的打包过程可以概括为以下步骤:

解析(Resolving): Webpack 从入口开始解析模块的依赖关系,找到每个模块的位置。

加载(Loading): 解析完成后,Webpack 将加载模块,这可能涉及到对文件的读取、转换和编译。

转换(Transformation): 加载器对模块进行转换,例如将 ES6 语法转换为 ES5、将 Sass 转换为 CSS 等。

打包(Bundling): 经过加载和转换后的模块被放置到一个或多个 bundle 中,这是由输出配置指定的。

输出(Output): Webpack 将 bundle 写入文件系统,生成最终的打包结果。

整个过程中,Webpack 通过使用各种配置选项、加载器和插件来灵活地处理不同类型的文件和任务,实现高度可定制的打包过程。Webpack 的灵活性和强大性使得它成为现代前端开发中的主流打包工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1269399.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【面试】typescript

目录 为什么用TypeScript&#xff1f; TS和JS的区别 控制类成员可见性的访问关键字&#xff1f; public protected&#xff09;&#xff0c;该类及其子类都可以访问它们。 但是该类的实例无法访问。 私有&#xff08;private&#xff09;&#xff0c;只有类的成员可以访问…

JSON.stringify方法详解 后端接受JSON数据格式

1、方法定义&#xff1a;JSON.stringify(value, replacer, space) 参数说明&#xff1a; value&#xff1a;js对象 replacer&#xff1a;替换对象&#xff0c;可以是一个方法、对象或数组&#xff0c;将value按照替换规则展示。 space&#xff1a;填充参数&#xff0c;可以是数…

LVS+Keepalived实验

实验前准备 主DR服务器&#xff1a;(ens33)192.168.188.11 ipvsadm、keepalived (ens33:0)192.168.188.188 备DR服务器&#xff1a;(ens33)192.168.188.12 ipvsadm、keepalived (ens33:0)192.168.188.188 Wbe服务器1&#xff1a;(ens33)192.168.188.13 (lo:0)192.168.188.188 W…

selenium使用记录

本文记录python环境下使用selenium的一些步骤 Step1&#xff1a;安装并配置驱动 pip install selenium # 使用pip在对应python中安装selenium包为了让selenium能调用指定的浏览器&#xff0c;需要下载对应浏览器的驱动程序&#xff08;这里以edge为例子&#xff09; #Firefo…

【Openstack Train安装】四、MariaDB/RabbitMQ 安装

本章介绍了MariaDB/RabbitMQ的安装步骤&#xff0c;MariaDB/RabbitMQ仅需要在控制节点安装。 在安装MariaDB/RabbitMQ前&#xff0c;请确保您按照以下教程进行了相关配置&#xff1a; 【Openstack Train安装】一、虚拟机创建 【Openstack Train安装】二、NTP安装 【Opensta…

改善厦门城市内涝积水问题,实时监测城市易涝积水点

近年来&#xff0c;城市内涝积水问题已成为中国许多城市面临的严峻挑战。特别是在厦门这样的海滨城市&#xff0c;由于其特殊的地理环境和气候条件&#xff0c;内涝问题尤为突出。传统的解决方法主要依赖于人工排查&#xff0c;然而&#xff0c;这种方式存在许多缺陷。 WITBEE万…

BEVFormer【人工智能】

BEVFormer 是一篇今年中稿 ECCV 2022 的论文&#xff0c;其中提出了一种纯视觉&#xff08;camera&#xff09;感知任务的算法模型&#xff0c;用于实现3D目标检测和地图分割任务。该算法通过提取环视相机&#xff08;Bird’s Eye View Camera&#xff09;采集到的图像特征&…

【产品设计】SaaS产品数据分析之指标与标签

数据分析能够应用到各个领域和岗位&#xff0c;那么在SaaS产品中的应用会是如何&#xff1f;本文将探索SaaS产品在数据分析中的应用&#xff0c;并对其指标与标签的设计进行总结分析&#xff0c;一起来看看吧。 数据分析是业务开展过程中&#xff0c;收集记录各种行为产生的数据…

vue2+element-ui npm run build打包后,在服务器打开报错

报错 页面的图标也显示不出来&#xff0c;如下 解决&#xff1a; 在build->utils.js文件里面加上publicPath: ../../&#xff0c;再打包发布一下就可以了 // Extract CSS when that option is specified// (which is the case during production build)if (options.extrac…

数据挖掘之时间序列分析

一、 概念 时间序列&#xff08;Time Series&#xff09; 时间序列是指同一统计指标的数值按其发生的时间先后顺序排列而成的数列&#xff08;是均匀时间间隔上的观测值序列&#xff09;。 时间序列分析的主要目的是根据已有的历史数据对未来进行预测。 时间序列分析主要包…

re:Invent 构建未来:云计算生成式 AI 诞生科技新局面

文章目录 前言什么是云计算云计算类型亚马逊云科技云计算最多的功能最大的客户和合作伙伴社区最安全最快的创新速度最成熟的运营专业能力 什么是生成式 AI如何使用生成式 AI后记 前言 在科技发展的滚滚浪潮中&#xff0c;我们见证了云计算的崛起和生成式 AI 的突破&#xff0c…

客服管理者如何有效管理客服团队,有哪些高效方式?

在如今的市场竞争中&#xff0c;客户服务是企业成功的关键因素之一。因此&#xff0c;客服团队的有效管理至关重要。客服管理者需要了解如何有效地管理客服团队&#xff0c;以确保客户的满意度和忠诚度&#xff0c;从而提高企业的竞争力。 以下是客服管理者如何有效管理客服团队…

【AI】Segment-Anything本地部署

Segment-Anything是Meta开源的图像分割模型&#xff0c;顾名思义&#xff0c;可以分割所有东西&#xff0c;感觉这东西可以用于遥感影像分割&#xff0c;于是找来源码测试一下。 项目地址&#xff1a;https://github.com/facebookresearch/segment-anything 1. 构建环境 首先…

论文笔记:Confidential Assets

Confidential Assets 描述了一种称为“保密交易”的方案&#xff0c;该方案模糊了所有UTXO的金额&#xff0c;同时保持了不创建或销毁硬币的公共可验证性。进一步将此方案扩展到“保密资产”&#xff0c;一种单一的基于区块链的分类帐可以跟踪多种资产类型的方案。将保密交易扩…

VSCode编译多个文件

打开tasks.json文件&#xff0c;找到"$ {file}“这一行。然后在其后面添加你想要编译的文件即可。 比如我这里是想要编译当前文件夹下的所有.cpp文件&#xff0c;那么我就直接把”$ {file}"给注释掉了&#xff0c;然后再使用通配符来代表所有.cpp文件。 最后解释以下…

支持向量机,硬间隔,软间隔,核技巧,超参数设置,分类与回归

SVM&#xff08;Support Vector Machine&#xff0c;支持向量机&#xff09;是一种非常常用并且有效的监督学习算法&#xff0c;在许多领域都有广泛应用。它可以用于二分类问题和多分类问题&#xff0c;并且在处理高维数据和特征选择方面非常强大。SVM算法的核心思想是通过找到…

vue3项目安装vite-plugin-mock 项目报错

vue3vite项目安装了vite-plugin-mock之后&#xff0c;根据官网配置使用&#xff0c;vscode会出现波浪线&#xff0c;启动项目&#xff0c;发现运行不了 解决办法&#xff1a; 安装vite-plugin-mock2.9.6的版本即可 pnpm install mockjs vite-plugin-mock2.9.6 -D

RabbitMQ的Web管理页面

访问页面 http://IP:15672/账号密码默认都是&#xff1a;guest 主页概览 Overview 显示当前RabbitMQ Broker的运行信息、连接信息、集群信息以及配置信息等。 连接 Connections 无论生产者还是消费者&#xff0c;都需要与RabbitMQ建立连接后才可以完成消息的生产和消费&#…

frida的hook代码:在python中格式,以及常用hook方法

js 写hook格式 首先frida的hook代码是通关JavaScript进行实现的&#xff0c;而且调用是通关python进行调用的 如果单独写一个js&#xff0c;就需要通关frida 命令进行启动了 首先聊一下frida的几个常用命令&#xff1a; -U&#xff1a;连接USB设备。-F&#xff1a;附加最前…

全球高纯铜靶材总体规模分析:行业现状及发展趋势

高纯铜靶材是指采用纯度在 4N&#xff08;Cu≥99.99%&#xff09;以上的金属铜生产的靶材&#xff08;N 即代表铜的纯度&#xff0c;N 前面的数字越大铜纯度越高&#xff09;。 高纯铜靶材是一种用于薄膜沉积工艺的材料&#xff0c;具有极高的纯度和特定的物理和化学性质。它通…