React中事件的处理
React 中使用 onClick 类似的写法来监听事件,注意 this 绑定问题 React 里严格遵循单项数据流,没有数据双向绑定,所以要处理两件事,第一是元素本身值的赋值,第二是值改变以后的事件,例如输入框需要设置 value 和 onChange 。
1.在 src -> components 文件夹中,再新建 CartSample.js ,具体代码如下:
import React, { Component } from 'react';
export default class CartSample extends Component {
// 状态的初始化一般放在构造器中
constructor(props){
super(props);
this.state = {
text: ''
}
// 为了在回调中使用 `this`,这个绑定是必不可少的
this.textChange = this.textChange.bind(this)
}
// 当 input 的值 text 发生变化的时候,我们让 textChang 去切换 input 的值
textChange (event){
this.setState({text: event.target.value})
}
render() {
return (
<div>
{/* 事件处理 */}
<div>
<input type="text" value={this.state.text} onChange={this.textChange}/>
</div>
</div>
);
}
}
注意:
- React 事件的命名采用小驼峰式(camelCase),而不是纯小写。且事件名称之后不能加 (),否则会直接执行
- 不能通过返回 false 的方式阻止默认行为。你必须显式的使用 preventDefault
2.然后在 src -> index.js 导入组件,并引用组件,查看结果,input 可以正常的输入值就是没有问题的。
我们必须谨慎对待 JSX 回调函数中的 this ,在 JavaScript 中,class 的方法默认不会绑定 this 。如果你忘记绑定 this.textChange 并把它传入了 onChange ,当你调用这个函数的时候 this 的值为 undefined。
如果你觉得使用 bind 很麻烦,还可以使用 箭头函数。
下面我们写一个添加并展示商品列表的功能,把 input 输入框的值添加到商品列表的数组中,并把列表展示到页面,具体代码如下:
import React, { Component } from 'react';
export default class CartSample extends Component {
// 状态的初始化一般放在构造器中
constructor(props){
super(props);
this.state = {
text: '',
goods: []
}
this.textChange = this.textChange.bind(this)
}
// 当 input 的值 text 发生变化的时候,我们让 textChang 去切换 input 的值
textChange (event){
this.setState({text: event.target.value})
}
addGoods = () => {
this.setState(prevstate => {
// prevstate.goods.push({
// id: prevstate.goods.length + 1,
// name: prevstate.text
// })
// react 官方希望传入与返回的对象不应该是同一个对象
return {
goods: [
...prevstate.goods,
{
id: prevstate.goods.length + 1,
name: prevstate.text
}
]
}
})
}
render() {
return (
<div>
{/* 事件处理 */}
<div>
<input type="text" value={this.state.text} onChange={this.textChange}/>
<button onClick={this.addGoods}>添加商品</button>
</div>
<ul>
{this.state.goods.map((good) => <li key={good.id}> {good.name} </li>)}
</ul>
</div>
);
}
}
解析:
在 addGoods 中,因为我们添加商品的时候需要拿到之前的 goods 数组,并且在点击添加商品按钮时再往 goods 数组添加新的商品,此时因为我们需要依赖于之前的值,所以用 prevstate ,可能你想到的是用 push ,上面代码也有,但是因为这种写法不符合 React 官方希望,React 希望我们传入与返回的对象不应该是同一个对象,比如在这个例子中我们想要更新的 goods 数组,需要是个全新的数组,而不是之前的那个,这就要求我们需要把之前数组的值加进来,然后再把 新的项 加入数组中,也就是代码中的写法。