React 事件处理
事件处理
React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:
- React 事件的命名采用 小驼峰式(camelCase) ,而不是纯小写。
- 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。
一、阻止默认行为
在 React 中另一个不同点是你不能通过返回 false
的方式阻止默认行为。你必须显式地使用 preventDefault
。
<form onsubmit="console.log('You clicked submit.'); return false">
<button type="submit">Submit</button>
</form>
在 React 中,可能是这样的:
function Form() {
function handleSubmit(e) {
e.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<button type="submit">Submit</button>
</form>
);
}
二、事件参数
function Form() {
function handleSubmit(e) {
e.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<button type="submit">Submit</button>
</form>
);
}
在这里, e
是一个合成事件,不用担心跨浏览器的兼容性问题。其他 React 事件,请查看参考指南 SyntheticEvent
另外,通常我们会为事件处理函数传递 额外的参数 。例如,若 id
是你要删除那一行的 ID,以下两种方式都可以向事件处理函数传递参数:
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
上述两种方式是等价的,分别通过 箭头函数 和 Function.prototype.bind
来实现
在这两种情况下,React 的事件对象 e
会被作为第二个参数传递。
如果通过箭头函数的方式,事件对象必须显式的进行传递,而通过 bind
的方式,事件对象以及更多的参数将会被隐式的进行传递。
三、 this
问题
class 组件中的自定义方法需要绑定 this
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// 为了在回调中使用 `this`,这个绑定是必不可少的
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
你必须谨慎对待 JSX 回调函数中的 this
,在 JavaScript 中,class 的方法默认不会 绑定 this
。如果你忘记绑定 this.handleClick
并把它传入了 onClick
,当你调用这个函数的时候 this
的值为 undefined
。
这并不是 React 特有的行为;这其实与 JavaScript 函数工作原理 有关。通常情况下,如果你没有在方法后面添加 ()
,例如 onClick={this.handleClick}
,你应该为这个方法绑定 this
。
如果觉得使用 bind
很麻烦,这里有两种方式可以解决。
1. 方法定义使用箭头函数方式
class fields 语法
class LoggingButton extends React.Component {
// This syntax ensures `this` is bound within handleClick.
handleClick = () => {
console.log('this is:', this);
};
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
2. 在回调中使用箭头函数
class LoggingButton extends React.Component {
handleClick() {
console.log('this is:', this);
}
render() {
// 此语法确保 `handleClick` 内的 `this` 已被绑定。
// 在回调中使用箭头函数
return (
<button onClick={() => this.handleClick()}>
Click me
</button>
);
}
}
此语法问题在于每次渲染 LoggingButton
时都会创建不同的回调函数。在大多数情况下,这没什么问题,但如果该回调函数作为 prop 传入子组件时,这些组件可能会进行额外的重新渲染。
我们通常建议 在构造器中绑定 或使用 class fields 语法 来避免这类性能问题。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: React 组件生命周期
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论