React 事件绑定的方式有哪些?区别?
一、是什么
在 React 中,事件绑定是组件与用户交互的基础。由于 React 组件有类组件和函数组件两种形式,事件绑定的方式和需要注意的问题也有所不同。
核心问题集中在两点:
- 类组件中的 this 指向:普通方法中
this默认不指向组件实例 - 函数组件中的引用稳定性:每次渲染创建新函数可能导致不必要的子组件重渲染
二、类组件的事件绑定
2.1 构造函数中 bind 绑定
优点:
- 每个方法只在构造函数中绑定一次,后续渲染不会创建新函数
- 传递给子组件时引用稳定,不会引起不必要的重渲染
缺点:
- 代码冗长,每个事件方法都需要在 constructor 中手动 bind
- 方法定义和绑定分散在不同位置,可读性差
2.2 Class Fields 箭头函数(推荐)
原理:箭头函数没有自己的 this,它会捕获定义时的外层 this。Class fields 中的箭头函数在实例创建时被赋值到实例上,this 固定指向组件实例。
优点:
- 代码简洁,定义即绑定
- 不需要 constructor
- 引用稳定,适合作为 props 传递
缺点:
- 每个实例都会创建独立的函数副本(不在原型上共享)
- 对于大量实例的场景(极少见)内存占用略高
2.3 render 中的箭头函数 / bind
这两种方式的问题是:每次渲染都创建新函数引用,传给使用了 React.memo / PureComponent 的子组件时会导致不必要的重渲染。
2.5 类组件方式对比
三、函数组件的事件绑定
函数组件没有 this 的问题,但面临函数引用稳定性的挑战。
3.1 内联箭头函数
对于简单的事件处理逻辑,内联箭头函数是最简洁的写法。在大多数场景下性能完全没问题。
3.2 独立函数声明
适合逻辑稍复杂的事件处理。注意每次渲染都会重新创建这些函数,但这通常不是性能瓶颈。
3.3 useCallback 稳定引用
当事件处理函数需要传递给被 React.memo 包裹的子组件时,使用 useCallback 保持引用稳定:
3.4 useCallback 的注意事项
3.5 React 19 Compiler 的影响
React 19 引入的 React Compiler 可以自动进行记忆化优化:
在 React Compiler 普及之后,useCallback 和 useMemo 将逐渐成为不需要手动编写的优化。
四、传递参数的最佳实践
列表场景中需要为每个项传递不同参数,有两种常用方案:
五、性能指导原则
-
不要过早优化:内联箭头函数在绑定到原生元素(div、button 等)时几乎没有性能影响。只有传递给被 memo 的子组件时才需要考虑引用稳定性
-
优先使用 class fields 箭头函数(类组件)或独立函数声明(函数组件)
-
useCallback的使用场景:- 作为 props 传递给
React.memo包裹的子组件 - 作为其他 Hook 的依赖项(如
useEffect的依赖) - 自定义 Hook 返回的函数
- 作为 props 传递给
-
React 19 Compiler:如果项目使用了 React Compiler,大部分手动记忆化将不再需要
六、总结
面试要点:能解释类组件中 this 丢失的原因(普通函数的 this 由调用方式决定),能说明各种绑定方式的性能影响,理解 useCallback 的适用场景和局限性,了解 React Compiler 对事件绑定优化的影响。