方法
下面我们看看如何给组件添加方法。方法可以和submit, click, change等事件绑定。
React里的事件
注意,React改变了事件的大小写。文本on被添加到事件名称的前面。还有事件使用驼峰命名法,典型的React 事件命名为:
on
发生的情况是文本 on 被添加到事件名称之前。此外,大小写更改名称,以便事件名称大写。基本上把 React 中的事件想象成这样:
on<Event name>
下面列举一些常见的事件命名:
| 事件名 | React的命名 |
|---|---|
| click | onClick |
| change | onChange |
| submit | onSubmit |
希望你明白了 :)
绑定事件&事件处理方法
通过设定可以绑定事件(React命名法)和方法,下面演示基于class组件的绑定实例:
<Component onClick={this.handler}>
基于class的组件和基于函数的组件看起来略有不同。让我们先介绍前者:
class Element extends React.Component {
constructor(props) {
super(props);
this.clicked = this.clicked.bind(this);
}
clicked() {
console.log('clicked');
}
render() {
return (
<button onClick={this.clicked}></button>
)
}
}
注意:
-
构造函数, 在构造函数中有一行代码绑定方法
clicked和this,该功能有多种实现方式:this.clicked = this.clicked.bind(this);绑定方法
clicked和this是必须的。当在组件内方法clicked()访问属性的时候,例如:clicked() { console.log(this.props.someAttribute); }如果绑定成功,会打印出
someAttribute的值,如果没有绑定就会报错。 -
在 JSX中. 在JSX中,可以使用下面这种方式来完成绑定:
<button onClick={this.clicked}></button>有了构造函数的绑定,我们才可以直接使用
this.linked, 否则this就没有linked这个方法。
Class组件还有另外两种的绑定方法
到目前为止,我们使用类似 handler.bind(this) 语句来绑定事件和方法,但看起来不太优雅,而且还需要为每个方法执行绑定操作。
有更好的方式吗? 实际上我们还有另外两种方式可供选择:
- 使用匿名函数lambda调用. 在
JSX表达式中插入箭头函数 - 将方法声明为类中的一个字段
使用匿名函数调用
我们来看看如何在标签中使用箭头函数:
class Element extends React.Component {
constructor() {
super();
}
state = {
str: 'test'
}
clicked(evt) {
console.log('clicked ' + this.state.str);
}
render() {
return (
<button onClick={(evt) => this.clicked(evt)}></button>
)
}
}
我们把这一行找出来:
<button onClick={(evt) => this.clicked(evt)}></button>
看看和第一种写法比较有什么不同,这是第一种:
onClick={this.clicked}
这是使用箭头函数:
onClick={(evt) => this.clicked(evt)}
使用使用箭头函数后就不需要在构造函数里面绑定了。还有我们可以在使用箭头函数时传入事件参数evt给回调函数,除此之外还可以传其他的参数:
render() {
return (
<button onClick={(evt) => this.clicked(evt, 'left')}></button>
<button onClick={(evt) => this.clicked(evt, 'right')}></button>
<button onClick={(evt) => this.clicked(evt, 'top')}></button>
<button onClick={(evt) => this.clicked(evt, 'down')}></button>
)
}
上例中传入 left, right, top, down四个不同的参数给绑定的函数。事件evt为第一个参数,自定义参数为第二个参数。
将方法声明为类中的一个字段
// 注意: 这是 实验性 语法。
下面我们再来演示一种方法:
class Element extends React.Component {
constructor() {
super();
//this.clicked = this.clicked.bind(this);
}
state = {
str: 'test'
}
clicked = () => {
console.log('clicked ' + this.state.str);
}
render() {
return (
<button onClick={this.clicked}></button>
)
}
}
> 注意,该语法需要babel 配置支持classProperties,参照 Props
注意比较之前的方法声明方式,这是旧的:
clicked() {
console.log('clicked ' + this.state.str);
}
这是新的:
clicked = () => {
console.log('clicked ' + this.state.str);
}
这是在class中声明方法的首选方式。
函数组件绑定事件方法
在函数组件中绑定事件方法略有不同,我们不需要考虑 this:
import React from 'react'
const AComponent = (props) => {
function handler(evt) => {
console.log('clicked');
}
return (
<div>
<button onClick={handler}></button>
</div>
)
}
export default AComponent;
上例所示,在函数组件中绑定事件方法更简单。
案例
-
运行
git clone克隆开始项目:git clone https://github.com/softchris/react-starter-project demo-methods cd demo-methods该开始项目基于教程使用webpack配置react项目
-
运行
npm install命令安装依赖包:npm install -
在 src 目录添加
Methods.js文件,并添加以下内容:import React from 'react'; class Method extends React.Component { constructor(props) { super(props) this.state = { direction: '' } } changeDirection (evt, direction) { this.setState({ direction }) } render() { return (<React.Fragment> <div>Direction: {this.state.direction}</div> <div> <button onClick={(evt) => this.changeDirection(evt, 'Top')}>Top</button> <button onClick={(evt) => this.changeDirection(evt, 'Left')}>Left</button> <button onClick={(evt) => this.changeDirection(evt, 'Right')}>Right</button> <button onClick={(evt) => this.changeDirection(evt, 'Bottom')}>Bottom</button> </div> </React.Fragment> ) } } export default Method;上例定义一个了class组件,将其中按钮点击onClick 事件绑定方法 changeDirection()。
-
在 index.js 文件中添加一行引入:
import Method from './Method'; -
找到以下代码
ReactDOM.render(做如下的修改:ReactDOM.render( <Method />, document.getElementById('app') ); -
在终端运行项目 npm start:
npm start -
打开浏览器访问 **http://localhost:8080\**. 查看结果:
在顶部看到方向状态。选择其中一个按钮,状态更新。
代码参考
小结
介绍如何给组件添加方法,再将方法绑定到事件。
- 在构造函数中绑定方法用于事件处理。
- 使用 lambda箭头函数,可以跳过绑定还可以将值传递给方法。