面试前端八股文十问十答第十期
相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新!
⭐点赞⭐收藏⭐不迷路!⭐
1)React.forwardRef 是什么及其作用
React.forwardRef
是一个高阶组件(Higher Order Component),用于在函数组件中向子组件传递 ref。它的作用是允许组件接收 ref,并将其传递给子组件,从而在函数组件中访问子组件的 DOM 节点或实例。通常情况下,函数组件无法直接使用 ref
属性,但通过 React.forwardRef
,我们可以在函数组件中使用 ref
。
使用方法如下所示:
const MyComponent = React.forwardRef((props, ref) => {
// 在这里使用 ref
return <input ref={ref} />;
});
在上面的例子中,MyComponent
是一个函数组件,通过 React.forwardRef
将 ref
传递给 input
元素,从而使得父组件可以操作 input
元素。
2)React Hooks 与 Class 组件对比
React Hooks 是 React 16.8 版本引入的一项特性,它使函数组件具有了类组件的一些特性,如状态管理和生命周期等。下面是 React Hooks 和 Class 组件的一些对比:
- 状态管理:在函数组件中,使用
useState
Hook 来管理状态,而在类组件中,使用this.state
和this.setState
。Hooks 使得状态管理更加简洁,不需要编写类,也不需要关注this
的指向问题。 - 生命周期:类组件具有生命周期方法,如
componentDidMount
、componentDidUpdate
和componentWillUnmount
等,而函数组件可以使用useEffect
Hook 来实现生命周期的功能。useEffect
可以代替类组件中的生命周期方法,并且更加灵活。 - 逻辑复用:在类组件中,逻辑复用需要使用高阶组件或者 Render Props,而在函数组件中,可以使用自定义 Hook 来实现逻辑复用,使得代码更加简洁和易于维护。
- 性能优化:由于 Hooks 的设计,可以更好地优化函数组件的性能。Hooks 的使用可以避免类组件中的一些性能问题,如不必要的重新渲染和内存泄漏等。
3)对 React Fiber 的理解
React Fiber 是 React 16 中引入的一种新的协调算法,用于实现可中断和恢复的渲染过程,以提高渲染的性能和交互体验。Fiber 的目标是使得 React 应用更加流畅,响应更快,并且更加可靠。
简单来说,React Fiber 可以将渲染过程分解为多个可中断的任务单元,然后根据优先级动态调度这些任务单元的执行顺序,从而实现优先级较高的任务优先执行,而优先级较低的任务可以被中断或延迟执行。这种方式可以使得 React 在进行复杂计算或大量渲染时,不会阻塞主线程,保持页面的响应性。
React Fiber 的引入使得 React 更加适用于构建大型和复杂的应用程序,并且可以提供更好的用户体验。同时,Fiber 也为未来的功能和优化提供了良好的基础。
4)React 性能优化手段
在 React 中,有许多性能优化手段可以帮助提高应用程序的性能和用户体验。以下是一些常见的 React 性能优化手段:
- 使用 React.memo 或 PureComponent:用于函数组件或类组件的浅层比较,以避免不必要的重新渲染。
- 避免不必要的渲染:在编写组件时,尽量减少不必要的渲染,可以通过
shouldComponentUpdate
方法或React.memo
来进行优化。 - 使用 Keys:在列表渲染时,为每个子元素提供一个稳定的唯一标识符(key),以便 React 能够正确地识别和更新列表中的元素,减少重新渲染的次数。
- 懒加载组件:通过 React.lazy 和 Suspense 来实现组件的懒加载,只在需要时才加载组件,从而减少初始加载时间。
- 使用 useCallback 和 useMemo:用于缓存函数和计算结果,避免在每次渲染时重新创建函数或计算值。
- 避免过度使用内联函数:内联函数会在每次渲染时重新创建,可以使用 useCallback 来缓存函数,以减少不必要的函数创建。
- 避免在渲染函数中进行重复计算:将重复计算的逻辑提取到渲染函数外部,以避免在每次渲染时都重新计算。
- 使用 React DevTools 进行性能分析:利用 React DevTools 工具来分析组件渲染的性能瓶颈,并进行优化。
5)React Redux
React Redux 是一个用于管理应用程序状态的库,它与 React 结合使用,提供了一种统一的方式来管理状态,并将状态与 UI 组件分离。Redux 的核心概念包括 Store、Action 和 Reducer:
- Store:存储应用程序的状态,并提供了一些方法来更新状态和订阅状态变化。
- Action:描述状态变化的纯 JavaScript 对象,包含一个
type
字段和一些其他数据字段。 - Reducer:纯函数,用于根据给定的 Action 来更新状态。
React Redux 提供了 connect
函数,用于将 React 组件连接到 Redux Store,并通过 Props 来访问状态和派发 Action。通过 React Redux,可以实现状态的全局管理和组件之间的通信,使得应用程序的状态管理更加清晰和可维护。
6)Webpack
Webpack 是一个模块打包工具,它可以将多个模块打包成一个或多个静态资源文件。Webpack 的核心概念包括 Entry、Output、Loader 和 Plugin:
- Entry:指定入口文件,Webpack 从入口文件开始分析和打包应用程序。
- Output:指定输出文件的名称和路径,Webpack 打包后的文件将会输出到指定的路径下。
- Loader:用于处理非 JavaScript 文件,如 CSS、图片等,将它们转换为模块并添加到依赖图中。
- Plugin:用于扩展 Webpack 的功能,执行一些额外的任务,如代码压缩、资源优化等。
Webpack 支持各种配置选项和插件,可以根据项目的需求进行灵活的配置和定制。它在现代前端开发中被广泛应用,用于构建复杂的应用程序,并提供了许多优化和性能调优的功能。
7)模块化
模块化是一种软件设计方法,通过将程序分解为独立且可重用的模块来提高代码的可维护性和可重用性。在前端开发中,模块化通常指的是将代码分割成多个文件,每个文件都负责一个特定的功能或模块,并通过导入和导出机制来组织和管理代码。
常见的模块化方案包括:
- CommonJS:Node.js 最初引入的模块化规范,使用
require
和module.exports
来导入和导出模块。 - ES Modules (ESM):ES6 标准引入的官方模块化规范,使用
import
和export
来导入和导出模块。 - AMD (Asynchronous Module Definition):一种异步模块加载规范,适用于浏览器环境。
- UMD (Universal Module Definition):一种通用的模块定义规范,兼容 CommonJS、AMD 和全局变量导出等多种使用场景。
模块化可以使代码更加清晰和易于维护,同时提供了诸如依赖管理、命名空间隔离等优点,是现代前端开发中的重要实践之一。
8)防抖和节流
防抖(Debounce)和节流(Throttle)是两种常用的性能优化技术,用于限制函数的执行频率,防止过度触发。
- 防抖(Debounce):在事件被触发后,等待一定的时间间隔,如果在这个时间间隔内没有再次触发事件,则执行函数;如果在这个时间间隔内又触发了事件,则重新计时。适用于如搜索框输入、窗口大小调整等频繁触发的事件。
- 节流(Throttle):在一定时间间隔内,只执行一次函数。即使在这段时间内触发多次事件,也只会执行一次函数。适用于如滚动事件、鼠标移动事件等高频触发的事件。
防抖和节流可以减少不必要的函数执行次数,提高性能和用户体验。
9)回流(重排)和重绘
在浏览器中,当 DOM 的结构或样式发生变化时,浏览器需要重新计算元素的几何属性(回流)和绘制元素的样式(重绘),以更新页面的显示。这两个过程可能会导致页面性能下降。
- 回流(Reflow):当 DOM 结构发生变化,影响了元素的几何属性(如尺寸、位置等)时,浏览器需要重新计算元素的几何属性,以确定元素的位置和大小。回流是一种比较昂贵的操作,可能会触发其他元素的重新排列和重新绘制,导致性能问题。
- 重绘(Repaint):当元素的样式发生变化,但不影响其几何属性时,浏览器只需要重新绘制元素的样式,而无需重新计算几何属性。重绘通常比回流消耗的资源要少一些。
为了减少回流和重绘,可以采取以下措施:
- 使用 CSS3 的 transform 和 opacity 属性来进行动画,而不是修改元素的位置和大小。
- 使用文档片段(DocumentFragment)来批量操作 DOM。
- 避免频繁地读取和修改元素的样式,可以将样式计算和操作集中在一起。
- 使用 CSS 的 will-change 属性来告诉浏览器哪些属性将会发生变化,以便浏览器优化渲染。
10)事件委托
事件委托是一种优化技术,通过将事件处理程序绑定到父元素而不是每个子元素,来提高性能和减少内存占用。当子元素触发事件时,事件会冒泡到父元素,父元素可以根据事件的目标来执行相应的处理逻辑。
事件委托的优点包括:
- 减少内存占用:通过将事件处理程序绑定到一个元素上,而不是多个元素,可以减少内存消耗。
- 动态添加和移除元素:当动态添加或移除子元素时,无需重新绑定事件处理程序,事件仍然可以正常工作。
- 简化代码:可以使用更少的代码来管理事件处理逻辑,提高代码的可维护性。
事件委托通常用于处理大量相似元素的相同事件,如列表项的点击事件、表单元素的输入事件等。
开源项目地址:https://gitee.com/falle22222n-leaves/vue_-book-manage-system
Github & Gitee 前后端总计已经 1000+ Star,1.5W+ 访问!
⭐点赞⭐收藏⭐不迷路!⭐