本文介绍: 虚拟DOM是React的一种概念,它是在内存中维护的一份虚拟的DOM树。useDeferredValue() 会将List组件渲染变得更加平滑,深层次看来是 defered value 引起的渲染会被标记为不紧急渲染,会被filters引起的渲染进行抢占,进而达到用户快速输入搜索场景页面抖动卡顿问题。在React 16之前,React的渲染过程递归的,当组件层次很深时,可能导致浏览器阻塞。这是因为直接DOM操作通常是昂贵的,而虚拟DOM的比较计算过程是在内存中进行的,相对来说更快。

1. class 组件函数组件区别

1. 语法不同

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

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

2. 状态的管理不同

类组件: 使用 this.statethis.setState管理组件的状态。

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

3. 声明周期方法不同

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

数组件: 使用 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

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

3. reduxreactredux区别

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

4. redux 中间件原理

Redux 中间件是一种在 action 被发起和 reducer 处理这个 action 之间进行操作机制中间件允许你在 Redux 应用中的 dispatch 过程拦截检查、或者修改 actionstate。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 函数做了什么

setState

  1. 接受新的状态: setState可以接受一个新的状态对象或一个函数,该函数返回新的状态。这个状态可以包含要更新的部分或全部组件状态。
  2. 将新的状态合并当前状态: React会将新状态与当前状态进行合并。这是因为setState可能是异步的,React可能会在后台批量处理多个setState调用。
  3. 触发组件更新流程: 一旦新状态被合并,React会触发组件的更新流程

render函数

  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 的灵活性和强大性使得它成为现代前端开发中的主流打包工具

原文地址:https://blog.csdn.net/iChangebaobao/article/details/134698454

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_31902.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注