昨天立的flag,今天搞起来
事件处理
在React中事件处理和一般的DOM的事件处理特别相似,但是也是有一些语法上面的不同
- React中是用的驼峰命名,在DOM中则是小写命名
- 在JSX中你是传递一个函数,在DOM则是传递的一个字符串
🌰:
在HTML中
<button onclick="activateLasers()">
Activate Lasers
</button>
在React中
<button onClick={activateLasers}>
Activate Lasers
</button>
还有一个不同的地方是,您能够使用return false 来阻止系统默认事件。必须调用preventDefault函数。再来一个🌰,在点击a标签的时候阻止默认跳转新页面的事件
在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>
);
}
在使用React的时候不需要立刻就添加监听(addEventListener),而是在元素被渲染到界面的时候添加监听
在使用ES6定义一个类类型的组件的时候,通常的形式是事件处理将会成为这个类的一个方法。
Toggle组件渲染了一个button,这个button的标题在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.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
这里的prevState就是this.state,setState传了一个函数进入,返回值是把当前状态取反。最后设置到相应的字段上面去。
第二个
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);
}
类的构造方法里面出现了,之前没见过的东西
this.handleClick = this.handleClick.bind(this);
这句话就是给绑定的事件添加监听,把this传递进去才能在handleClick函数中使用this。
一定要注意this在JSX回调中的含义,在Javascript中类方法不会默认绑定。如果忘记将this.handleClick绑定并且传递到了onClick,this将会是undefined当函数被调用的时候。
这不是React特有的属性,这属于js的方法调用准则。大体上来说,如果引用了一个方法,这个方法后面没有带(),例如 onClick={this.handleClick},那么你就要把这个方法进行绑定。
如果你觉得这个绑定很烦人,很繁琐,有一些方法可以解决这个问题。
第一种
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>
);
}
}
这种方法在React App中是默认开启的,这里有一个警告Warning: this is experimental syntax.不懂啥意思。。。应该是不建议这么用吧。
还有一种方法,也有问题存在,可以忽略看此步骤
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>
);
}
}
这里的问题是每次当组件被渲染的时候后就会重新创建一个回调函数。在大多数的情况下是没有问题的,但是如果这里的回调作为一个props的参数向下传递到内部组件中的时候,可能会造成额外的渲染。
最后还是建议使用最开始讲的那种方式,虽然有些繁琐,但是作为初学者,最不容易踩到坑里。
传递参数
在一个循环的内部,我们通常会传递额外的参数到事件处理中。例如,🌰
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
上面两种方法都是OK的,一种使用的是箭头函数,一种使用的是函数属性绑定。
在箭头函数中e表示React的事件,如果是箭头函数中,我们必须明确的传递这个参数,但是bind的方法是默认自己传递这个参数的。
网友评论