本文是本人自己辛苦翻译的,请转载的朋友注明,翻译于Z.MJun的简书 ,感谢!<翻译不容易啊>
翻译于2017年6月26日,原文
处理事件的React元素,与DOM元素处理事件相似。
- React 事件使用驼峰式命名,不要使用全小写。
- 使用JSX来传一个事件执行函数,不要使用字符串。
HTML的样式如下:
<button onclick="activateLasers()">
Activate Lasers
</button>
在React使用以下方法
<button onClick={activateLasers}>
Activate Lasers
</button>
另一个不同点,在react中不能使用返回false。必须调用preventDefault
。Html如下:
<a href="#" onclick="console.log('The link was clicked.'); return false">
Click me
</a>
React如下:
function ActionLink() {
function handleClick(e) {
e.preventDefault();
console.log('The link was clicked.');
}
return (
<a href="#" onClick={handleClick}>
Click me
</a>
);
}
这里的e
是一个虚拟的事件。React定义的这些虚拟的事件满足W3C spec。所以不需要担心浏览器兼容问题。想了解更多查看SyntheticEvent
。
当使用React的时候,不需要如DOM元素调用addEventListener
方法添加监听者。只需要,在初始化渲染的时候提供一个监听者。
当使用ES6类来定义一个组件,常见的模式是将事件处理程序作为类中的一个方法。如,Toggle
组件渲染一个按键,会让用户切换ON
或者OFF
状态:
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
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>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
Try it on CodePen.
在JSX的回调,this
的含义需要反复理解。在JS里面,类方法中没有默认绑定。如果你忘记了绑定this.handleClick
,和点击onClick
,this
将会警告未定义。
这个并不是React特有的行为。这是JS的函数的一部分。一般来说,如果你是一个没有()
方法后,如onclick = {this.handleclick }
,你应该绑定方法。
可以使用以下两个方法来绑定时间。如果使用初始化绑定(property initializer syntax),可以使用初始化的属性来绑定回调方法。
class LoggingButton extends React.Component {
// This syntax ensures `this` is bound within handleClick.
// Warning: this is *experimental* syntax.
handleClick = () => {
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
这个语法是默认能用在Create React App下的。
如果你不想使用这个方法,还可以使用回调中动态加载方法。
class LoggingButton extends React.Component {
handleClick() {
console.log('this is:', this);
}
render() {
// This syntax ensures `this` is bound within handleClick
return (
<button onClick={(e) => this.handleClick(e)}>
Click me
</button>
);
}
}
这个语法问题,不同的回调被创建每个时间点来表达LoggingButton
。多数情况下,都可以的。但是,如果这个回调是要穿个低级的组件,这些组件就需要创建额外的重新渲染。比较推荐在constructor
绑定或者使用初始化定义,来避免这个实现问题。