在react的elements上绑定事件和在dom上绑定事件极为相似,但是还是有一些语法上的不同:
** react的事件用驼峰命名法 ,而不是小写命名法 **
** 你需要传递一个函数名作为一个事件而不是一个字符串 **
比如在传统html中:
<button onclick="activateLasers()">
Activate Lasers
</button>
在react中会有些许不同:
<button onClick={activateLasers}>
Activate Lasers
</button>
另外一个不同是你不能返回一个false去阻止默认事件,你必须调用preventDefault这个函数。比如,在html中,为了去阻止默认的link跳转到其他页面的事件,你可以这样写:
<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的标准定义了这些事件,所以不用去担心浏览器的兼容问题。
在 react的机制中,你不需要去用addEventListener去给dom节点绑定事件,你仅仅只需在这个元素创建时提供一个监听器就行。
当你使用ES6的class去定义一个组件时,一个通用的模式是将一个方法定义为一个事件处理函数。比如,下面这个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')
);
你需要注意this在JSX中的含义。在javascript中,类中的方法不是默认是不受绑定的,如果你忘了去显式的绑定并且将其传递给onClick事件,this将会被当作未定义,当这个类函数被执行的时候。
这不是react的原因,而是javascript本身设计的原因* 【如果你有疑惑,推荐你看看《你不知道的javascript上卷》】*。通常,要是你将一个函数名赋值给了一个事件,比如onClick={this.handleClick},这时你就需要显式的绑定它。
如果关于绑定这个问题让你变的困扰的话,这里有两个方法可以让你避免出错:
- 使用赋值尖头函数的方式:
class LoggingButton extends React.Component {
handleClick = () => {
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
- 在element上使用尖头函数绑定:
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的再次渲染。在大多数情况下,这时极好的特性,但是如果这个会掉函数作为props被传递给子组件呢?这些子组件可能会引发我们不希望的渲染。所以我们建议显示的绑定或者第一种方法,以此来避免性能上的问题。
网友评论