getDerivedStateFromError
React 组件生命周期方法之一,用于处理组件在渲染过程中出现的错误。它是从 React 16.6 版本引入的。
当组件的子组件抛出错误时,或者在组件的生命周期方法中发生错误时,React 将调用getDerivedStateFromError方法。这个方法是一个静态方法,需要在组件类中实现。它接收一个错误对象作为参数,并返回一个更新的状态对象
class ErrorBoundary extends React.Component {
static getDerivedStateFromError(error) {
// 返回一个新的状态对象,用于展示错误信息
return { hasError: true }
}
constructor(props) {
super(props)
this.state = { hasError: false }
}
render() {
if (this.state.hasError) {
return <div>发生了错误。</div>
}
return this.props.children
}
}
// 使用 ErrorBoundary 组件包裹可能会出错的子组件
;<ErrorBoundary>
<ChildComponent />
</ErrorBoundary>使用Hooks要遵守哪些原则?
只在最顶层使用 Hook (不要在循环,条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层调用他们。)
只在 React 函数中调用 Hook (在 React 的函数组件、自定义 Hook 中调用 Hook)
为什么要加这些限制? React中每个组件都有一个对应的 FiberNode对象,这个对象上有个属性叫 memoizedState,在函数组件中,fiber.memoizedState存储的就是Hooks单链表,单链表中每个hook节点没有名字和key,只能通过顺序来记录他们的唯一性。 如果在循环、条件或者嵌套中使用hook,当组件更新时,这个hooks顺序会乱套,单链表的稳定性就破坏了。
React Fiber它的目的是解决什么问题?
React15 的 StackReconciler 方案由于递归不可中断问题,如果 Diff 时间过长(JS计算时间),会造成页面 UI 的无响应(比如输入框)的表现,vdom 无法应用到 dom 中。
为了解决这个问题,React16 实现了新的基于 requestIdleCallback 的调度器(因为 requestIdleCallback 兼容性和稳定性问题,自己实现了 polyfill),通过任务优先级的思想,在高优先级任务进入的时候,中断 reconciler。
为了适配这种新的调度器,推出了 FiberReconciler,将原来的树形结构(vdom)转换成 Fiber 链表的形式(child/sibling/return),整个 Fiber 的遍历是基于循环而非递归,可以随时中断。
更加核心的是,基于 Fiber 的链表结构,对于后续(React 17 lane 架构)的异步渲染和 (可能存在的)worker 计算都有非常好的应用基础
怎么防止HTML被转义?
dangerouslySetInnerHTML
react 函数式组件有没有生命周期
在 React 中,函数式组件是一种更简洁和轻量级的组件形式,通常以函数的形式定义,而不是类。函数式组件在 React 16.8 版本引入了 Hooks 之后变得更加强大,Hooks 提供了一种在函数式组件中使用状态和其他 React 特性的方式。
在传统的意义上,函数式组件并没有像类组件那样的生命周期方法。类组件有一系列生命周期方法,如 componentDidMount、componentDidUpdate 和 componentWillUnmount,用于处理组件的挂载、更新和卸载等阶段。
然而,使用 Hooks,函数式组件可以使用一些特定的 Hook 函数来实现类似生命周期的功能。以下是一些常用的 Hook 函数:
- useState:用于在函数式组件中使用状态。
- useEffect:在组件渲染完成后执行副作用操作,相当于 componentDidMount、componentDidUpdate 和 componentWillUnmount 的组合。
- useContext:用于从 React Context 中获取上下文。
- useReducer:在函数式组件中使用 Redux 风格的状态管理。
- useCallback 和 useMemo:用于性能优化,避免不必要的重新计算。
React如何加载异步组件
import React, { Suspense } from 'react'
const LazyComponent = React.lazy(() => import('./LazyComponent'))
function App() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
</div>
)
}react 为什么需要合成事件?
- 跨浏览器兼容:合成事件首先抹平了浏览器之间的兼容问题,另外这是一个跨浏览器原生事件包装器,赋予了跨浏览器开发的能力;
- 性能优化:对于原生浏览器事件来说,浏览器会给监听器创建一个事件对象。如果你有很多的事件监听,那么就需要分配很多的事件对象,造成高额的内存分配问题。React 通过合成事件实现了事件委托机制, 对于合成事件来说,有一个事件池专门来管理它们的创建和销毁,当事件需要被使用时,就会从池子中复用对象,事件回调结束后,就会销毁事件对象上的属性,从而便于下次复用事件对象 。
react 合成事件特点
- 我们在 jsx 中绑定的事件(demo中的handerClick,handerChange),根本就没有注册到真实的dom上。是绑定在document上统一管理的。
- 真实的dom上的click事件被单独处理,已经被react底层替换成空函数。
- react并不是一开始,把所有的事件都绑定在document上,而是采取了一种按需绑定,比如发现了onClick事件,再去绑定document click事件。
为什么推荐使用函数式组件?
代码简洁:避免this绑定和类语法冗余 逻辑复用:自定义Hooks比HOC更灵活 性能优化:Hooks提供更细颗粒度的控制(如useMemo) 未来兼容:新特性(如并发模式)优先支持Hooks
Hooks的限制和突破
规则:只能在函数顶层调用Hooks 原理:依赖调用顺序的链表结构记录状态 解决方案:使用eslint-plugin-react-hooks强制规范
事件合成设计目的与核心原理
- 跨浏览器一致性
统一不同浏览器的事件处理接口(如event.target的行为) 修复浏览器兼容性问题(如IE事件模型差异)
2 .性能优化
事件委托:将事件绑定到根节点(React 17+ 为应用根DOM),而非每个子元素 事件池化(Event Pooling):复用事件对象,减少内存开销
- 扩展能力
支持自定义事件类型(如 onDoubleClick) 实现高级功能(如事件优先级调度)
diff 算法
React采用逐层递归比较,但不会跨层级追踪节点变化,当父节点类型相同时,递归比较其他子节点
为什么列表必须使用key?
帮助React识别元素身份,在顺序变化时高效复用DOM节点,避免以下问题:
- 不必要的子组件重新渲染
- 表单元素状态错乱(如输入框内容错位)
Fiber
Fiber的诞生背景
- 旧版协调算法瓶颈
- 递归不可中断:同步遍历整个虚拟DOM树,长时间占用主线程
- 卡顿问题:复杂组件树更新导致掉帧(如大型列表、动画场景)
- 目标
- 实现增量渲染,支持异步可中断的更新
- 旧版协调算法瓶颈
Fiber核心设计思想
时间切片
- 将渲染任务拆分为多个小任务(Fiber节点)
- 利用浏览器空闲时段(requestIdleCallback)分片执行
优先级调度
- 用户交互(如输入)优先于数据更新(如API响应)
可恢复工作单元
- 保存中间状态,允许暂停/恢复渲染流程
Fiber节点数据结构
- 每个Fiber节点对应一个组件实例或DOM节点,包含以下核心属性:
Fiber双缓冲机制
React维护两颗Fiber树已确保更新无冲突
- Current Tree:当前已渲染的UI对应的Fiber树
- WorkInProgress Tree:正在构建的新Fiber树
切换流程:更新完成后,WorkInProgress Tree树变为Current树
如何实现可中断更新
通过链表结构存储Fiber节点,记录遍历进度。每次处理一个Fiber后检查剩余时间片,不足时保存当前进度,将控制权交还浏览器
协调阶段和提交阶段的区别
协调阶段负责计算变更(可中断),提交阶段执行DOM操作(同步不可中断)
.React核心设计思想
组件化设计
- 原子化构建:UI分解为独立的功能单元(如函数式组件/类组件)
- 组合模式:通过props嵌套实现组件树结构
- 隔离型:每个组件维护自身状态和样式(CSS-in-JS生态支持)
- 复用机制:高阶组件(HOC)与自定义Hooks实现逻辑复用
声明式编程范式
- 状态驱动:UI=f(state)的数学表达式(无需手动操作DOM)
- 抽象渲染:开发者专注描述目标状态,框架处理渲染细节
- 幂等性保证:相同state必定输出相同视图(确定性原则)
高效更新引擎
- 虚拟DOM层:内存中轻量级DOM表示(对象树结构)
- Diff算法优化:启发式O(n)复杂度比较策略(基于树遍历策略)
- 批量更新策略:自动合并setState操作(异步更新策略)
- 渲染流水线:Fiber架构实现可中断渲染(并发模式)
单向数据控制
- 严格数据通道:props自上而下传递(严禁子级逆向修改)
- 状态托管:通过Context/Redux实现跨层级通信
- 副作用隔离:Hooks机制约束副作用边界(useEffect依赖链)
这些原则使React具备:高维护性(组件解耦)、高性能(智能更新)、可预测性(数据流透明)。
