React 中的事件跟传统的 DOM 元素的事件区别不大,基本原理是相同的,有一些细节上的差异。本节就来瞄准 React 条件下的事件处理。
先来看看基本语法,看看对比 DOM 元素事件有哪些差别。
首先,React 事件是用骆驼拼写法命名的,而不是小写,事件处理器( Event Handler )是函数,而不是字符串。
<button onclick="handleClick()">
Click
</button>
对于 DOM 元素,事件名 onclick
全部小写,等号后面是一个字符串。
<button onClick={handleClick}>
Click
</button>
到 React 这里 onclick 的 on 后面的 C 变成了大写,也就是采用了骆驼拼写法,同时后面的事件处理器是用大括号包裹的一个函数,不再是字符串了。
其次,React 中防止默认行为必须使用 preventDefault ,不能用 return false
了。
const ActionLink = () => {
const handleClick = e => {
e.preventDefault()
console.log('Clicked')
}
return (
<a href="/sth" onClick={handleClick}>
Click me
</a>
)
}
注意,这里的 e
跟 DOM 条件下的也有差别,主要是拥有了更好的浏览器兼容性。React 事件的详细参考资料在官方文档上可以找到 https://reactjs.org/docs/events.html 。
关于,事件处理的基本语法咱们就聊到这里。
实际中非常常见的一种使用情形就是,在事件处理函数中修改 state ,state 一变,界面就会自动更新了。下面来看看事件跟 state 配合使用的例子。
class Toggle extends Component {
state = { isToggleOn: true }
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'))
当采用 ES6 class 定义组件的时候,常见的做法就是用 class 的方法作为事件处理函数( handler )。例如,这里的 Toggle 组件首先初始化了 state ,把 isToggleOn 意思是”开关打开“,设置为 true 。
接下来,使用 create-react-app 环境下支持的这种类字段新语法,handleClick 直接赋值为一个 es6 函数,这样的好处是里面直接使用 this 而无需绑定。由于 this.setState
的异步性,所以参数不能传入对象,而要传入一个函数,才能稳妥的基于之前的状态来获得最新状态值。
渲染了一个按钮,监听 onClick 事件,传入 this.handleClick 作为处理函数。
浏览器中,点按钮,可以让用户在 ON 和 OFF 直接切换。
关于如何通过事件响应函数来修改 state ,就演示到这里。
接下来看看如何给事件处理函数传入参数。
import React from 'react'
import ReactDOM from 'react-dom'
class List extends React.Component {
deleteRow = id => {
console.log(id)
}
render() {
return <button onClick={() => this.deleteRow(2)}>Delete Row</button>
}
}
ReactDOM.render(<List />, document.getElementById('root'))
比如有一个列表,这里封装成 List 组件。里面 deleteRow 需要接受行号,这里就是 id ,才能知道要删除哪一行的内容。
下面 render 中,咱们就不渲染一个列表了,直接给一个按钮, 传参的正确方式就是添加一个 es6 的箭头函数,把本行 Id ,例如 2 传递给处理函数。
浏览器中,点按钮,打印出了 2 。
那如果 deleteRow 中,还想要事件对象呢?
deleteRow = (id, e) => {
console.log(id, e)
}
render() {
return <button onClick={e => this.deleteRow(2, e)}>Delete Row</button>
}
大括号中传入一个回调函数,第一个参数就是 e ,这样,把 e 传递给 deleteRow 使用即可。到浏览中就可以看到 id 和 e 都打印出来了。
关于如何给事件处理函数传参数,就聊到这里。
这节聊的是 React 的事件处理,主体内容就是这么多。关键知识点有这么几个:第一,React 的事件处理跟 DOM 事件处理思路一致,有几个小的细节差异需要记住。第二,React 事件最常见的使用情形之一就是在事件处理函数中去修改 state 。第三,事件处理函数中也可以传递参数。
参考