React中onChange={this.fileSelected}与箭头函数写法的区别及适用场景
React事件处理两种写法的区别与适用场景
嘿,这个问题问得特别实在——很多刚接触React的开发者都会在这两种事件绑定写法上犯懵,我来给你把它们的区别、坑点和适用场景讲得明明白白~
核心差异先搞懂
这两种写法本质上是传递给事件处理器的内容不同:
onChange={this.fileSelected}:直接把fileSelected函数的引用传给了事件。React触发事件时,会自动把事件对象event作为第一个参数传入这个函数。但这里要注意this的指向问题,如果fileSelected是普通的类方法,直接传的话this会丢失(默认是undefined),得提前做绑定(比如构造函数里bind,或者用类字段箭头函数定义方法)。onClick={() => this.clearDisplay()}:这是创建了一个全新的箭头函数,当事件触发时,才会执行箭头函数内部的this.clearDisplay()。箭头函数会自动继承当前组件实例的this,所以不用额外处理绑定,还能自由传递自定义参数。
具体区别拆解
1. 参数传递灵活性
- 直接传引用:只能拿到React自动传递的
event对象,如果需要额外参数(比如列表项的ID),没法直接传,得用其他技巧(比如给元素加data-*属性然后从event.target里取)。 - 箭头函数包裹:可以轻松传递自定义参数,比如遍历列表时:
onClick={() => this.handleDelete(todo.id)},非常直观。
2. this指向问题
- 直接传引用:如果是普通类方法(非箭头函数定义),
this会指向undefined(严格模式下),必须提前绑定:
或者用类字段箭头函数定义方法,自动绑定constructor(props) { super(props); // 手动bind this this.fileSelected = this.fileSelected.bind(this); }this:fileSelected = (event) => { console.log(this.state, event.target.files); } - 箭头函数包裹:箭头函数本身没有
this,会继承外层作用域的this(也就是组件实例),所以不用额外绑定,直接用this访问组件的状态和方法就行。
3. 性能开销
- 直接传引用:函数实例是固定的,每次组件渲染时不会创建新的函数,不会给子组件带来不必要的重渲染(如果子组件用了
React.memo做优化的话)。 - 箭头函数包裹:每次组件渲染都会创建一个新的箭头函数实例。如果把这个箭头函数传给子组件作为props,子组件会因为props变化而触发重渲染,除非子组件做了深度比较的优化。不过如果组件本身不会频繁重渲染,这点性能影响完全可以忽略。
适用场景
用onChange={this.fileSelected}的情况
- 不需要传递自定义参数,只需要使用React提供的
event对象。 - 追求性能优化,尤其是在给子组件传递事件处理器时(配合
React.memo避免子组件无意义重渲染)。 - 已经通过类字段箭头函数或构造函数
bind处理好this指向的类组件方法。
用onClick={() => this.clearDisplay()}的情况
- 需要给事件处理函数传递自定义参数(比如列表项ID、索引等),这是最常见的场景。
- 快速实现简单的事件逻辑,不想额外处理
this绑定(比如临时的弹窗关闭、状态重置等简单操作)。 - 组件本身是一次性渲染或者重渲染频率很低的,性能开销可以忽略不计。
举个直观的例子
直接传引用的正确写法(类字段箭头函数)
class FileUploader extends React.Component { fileSelected = (event) => { this.setState({ selectedFile: event.target.files[0] }); } render() { return <input type="file" onChange={this.fileSelected} />; } }
箭头函数传递参数的写法
class TodoList extends React.Component { deleteTodo = (todoId) => { this.props.onDelete(todoId); } render() { return this.props.todos.map(todo => ( <div key={todo.id} onClick={() => this.deleteTodo(todo.id)}> {todo.text} <button>删除</button> </div> )); } }
简单总结一下:如果不需要额外参数、看重性能,就用直接传函数引用;如果要传参数或者图省事快速实现,就用箭头函数包裹~
内容的提问来源于stack exchange,提问作者Molly Christian
相关产品推荐
相关产品推荐

