面试 React 框架八股文十问十答第一期
作者:程序员小白条,个人博客
相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新!
?点赞?收藏?不迷路!?
1)React 生命周期是怎样的?
React组件有三个主要阶段的生命周期:
- Mounting(挂载阶段):
constructor()
: 初始化state和绑定事件处理函数。static getDerivedStateFromProps()
: 从属性初始化state。render()
: 根据state和props渲染组件的UI。componentDidMount()
: 组件挂载后调用,通常进行异步操作、数据获取等。
- Updating(更新阶段):
static getDerivedStateFromProps()
: 当组件接收到新的props时调用。shouldComponentUpdate()
: 返回一个布尔值,判断是否重新渲染组件,默认返回true。render()
: 根据state和props重新渲染组件的UI。getSnapshotBeforeUpdate()
: 在render之后、更新之前调用,通常用于获取更新前的DOM状态。componentDidUpdate()
: 组件更新后调用,通常进行DOM操作、网络请求等。
- Unmounting(卸载阶段):
componentWillUnmount()
: 组件即将被卸载时调用,通常用于清理定时器、取消网络请求等。
2)虚拟 DOM 实现原理?
虚拟DOM是React用来提高渲染性能的一种机制。其基本原理是在内存中维护一份DOM的虚拟副本,当状态发生变化时,首先在虚拟DOM上进行操作,然后通过比较虚拟DOM和实际DOM的差异(称为协调或reconciliation),最终只对实际DOM中需要变化的部分进行更新。
主要步骤:
- 创建虚拟DOM树: 组件的状态或属性发生变化时,React会创建一颗新的虚拟DOM树。
- Diff算法比较差异: 对比新旧虚拟DOM树,找出需要更新的部分。
- 更新实际DOM: 只对需要变化的部分进行实际DOM操作,提高性能。
3)React 的请求应该放在哪个生命周期中?
数据请求通常放在componentDidMount
生命周期方法中。这是因为componentDidMount
在组件挂载后调用,适合进行初始化数据的获取。在这个阶段发起请求可以确保组件已经被渲染到DOM中,避免不必要的重复渲染。
4)setState 到底是异步还是同步?
setState
在React中是异步的。当你调用setState
时,React会将状态更新放入一个队列中,然后异步地执行队列中的状态更新。这种异步机制有助于性能优化,因为React可以批量处理状态更新,避免不必要的重新渲染。
如果需要在setState
后执行某些操作,可以在setState
的第二个参数中传入一个回调函数,该回调函数将在setState
完成并且组件开始重新渲染时被调用。
5)React 组件通信如何实现?
React组件通信有多种方式:
- 父子组件通信: 通过props将数据从父组件传递给子组件。父组件可以通过props传递数据和回调函数给子组件,实现父组件向子组件传递数据和方法。
- 子父组件通信: 子组件可以通过props接收父组件传递的数据和方法。通过在子组件中调用父组件传递的方法,实现子组件向父组件传递信息。
- 兄弟组件通信: 如果兄弟组件之间没有直接的父子关系,可以通过共享状态提升到它们的最近公共父组件,或者使用一些状态管理工具(如Redux、Context API)来实现兄弟组件之间的通信。
- 使用Context API: React的Context API可以在组件树中传递数据,避免了手动层层传递props的麻烦。通过
React.createContext
创建Provider和Consumer,组件可以订阅Provider的值。 - 使用状态管理库: 使用像Redux、Mobx这样的状态管理库,可以将状态集中管理,实现组件之间的通信。
6)React 如何实现组件复用?
React实现组件复用的主要方式包括:
- 组件组合: 将多个小组件组合在一起形成一个复杂的组件,通过嵌套组件的方式来实现复用。
- Props: 利用组件的props属性传递不同的数据和配置,使同一个组件能够展示不同的内容。
- 高阶组件(HOC): 高阶组件是一个函数,接受一个组件作为参数并返回一个新的组件,通过这种方式可以对现有组件进行包装,添加额外的功能或逻辑。
- Render Props: Render Props是指通过组件的prop将一个函数传递给子组件,子组件通过调用这个函数来获取需要的数据或功能。
- Hooks: 使用React Hooks(如useState、useEffect)来实现逻辑的复用,可以将共享的状态和副作用提取到自定义的hook中,然后在多个组件中复用。
7)mixin、hoc、render props、react-hooks的优劣如何?
- Mixin:
- 优点:简单,能够实现代码的重用。
- 缺点:可能导致命名冲突、难以维护,不够灵活。
- HOC(高阶组件):
- 优点:提供了一种将组件逻辑复用的机制,可用于横切关注点的封装。
- 缺点:嵌套过多时可能难以理解,容易出现命名冲突。
- Render Props:
- 优点:通过props传递函数,更加灵活,可以选择性地共享逻辑。
- 缺点:嵌套过多时可读性下降。
- React Hooks:
- 优点:简洁,逻辑清晰,可在函数组件中共享状态和副作用。
- 缺点:某些场景下使用Hooks可能需要重新组织组件的结构。
8)你是如何理解 fiber 的?
Fiber是React 16引入的一种新的协调引擎,用于实现React的协调和调度。它主要解决了之前的"stack reconciliation"方式在处理大型应用时可能导致的性能问题。
Fiber的关键概念和特点包括:
- 可中断的: Fiber允许React在渲染过程中中断、优先级调度和恢复,使得React可以更灵活地处理用户交互和渲染。
- 优先级调度: Fiber引入了优先级概念,允许React根据任务的紧急程度决定何时处理更新,从而更好地响应用户输入和保持流畅的用户体验。
- 增量渲染: Fiber实现了增量渲染,可以将渲染任务分割成多个小任务,分散到多个帧中执行,提高了渲染的效率。
- 可组合的: Fiber的架构使得React能够更容易地实现一些高级的特性,比如异步渲染、错误边界等。
9)异步渲染有哪两个阶段?
异步渲染有两个主要阶段:
- Reconciliation(协调阶段): 在这个阶段,React会比较新旧虚拟DOM树的差异,找出需要更新的部分,生成更新的任务。
- Commit(提交阶段): 在这个阶段,React会将协调阶段生成的更新任务应用到实际的DOM上,完成渲染。这个阶段是同步的,因为它直接涉及到对DOM的操作。
异步渲染通过将工作分为两个阶段,使得React能够更好地响应用户输入,提高了渲染的效率。
10)你对 Time Slice 的理解?
Time Slice是React中的一项特性,旨在改善大型React应用的用户体验。它允许React在多个帧中分割工作,以保持页面的响应性。
具体来说,Time Slice使用了浏览器的空闲时间(Idle Callback API),将一个耗时较长的任务分割成小块,在多个帧中逐步执行。这样,长任务的执行不会阻塞主线程,从而避免了页面的卡顿和用户交互的延迟。
Time Slice的实现涉及到React调度器的改进,它使得React可以更加灵活地处理任务的执行,根据优先级和空闲时间智能地分配工作。这有助于提高应用的整体性能,特别是在大型和复杂的应用中。