Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
130 lines (90 sloc) 4.42 KB

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 一变,界面就会自动更新了。下面来看看事件跟 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 。第三,事件处理函数中也可以传递参数。

参考