React中事件的处理

React中事件的处理

React 中使用 onClick 类似的写法来监听事件,注意 this 绑定问题 React 里严格遵循单项数据流,没有数据双向绑定,所以要处理两件事,第一是元素本身值的赋值,第二是值改变以后的事件,例如输入框需要设置 value 和 onChange 。

import React, { Component } from "react";

export default class CardSample extends Component {
    //状态的初始化一般放在构造器中
    constructor(props) {
        super(props);
        this.state= {
            text: '',
            goods: []
        }
        //为了在回调中使用'this',这个绑定式必不可少的
        this.textChange = this.textChange.bind(this);
    }
    //input的值text发生变化的时候,调用textChange去切换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, //获取原来的商品填充到新的数组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)=>
                           return <li key={ good.id }>{ good.name }</li>
                        )
                    }
                </ul>
            </div>
        )
    }
}

注意:

  • React 事件的命名采用小驼峰式(camelCase),而不是纯小写。且事件名称之后不能加 (),否则会直接执行
  • 不能通过返回 false 的方式阻止默认行为。必须显式的使用 preventDefault
  • 必须谨慎对待 JSX 回调函数中的 this , JavaScript 中,class(类) 的方法默认不会绑定 this 。如果忘记绑定 this.textChange 并把它传入了 onChange ,当调用这个函数的时候 this 的值为 undefined。如果觉得使用 bind 麻烦,还可以使用 箭头函数

一、React组件中的事件处理函数

   1、constructor函数中bind

      class ReactEvent extends Component {

constructor(props) {

super(props);

this.handleClick = this.handleClick.bind(this);

}

handleClick() {

console.log('Click');

}

render() {

return <button onClick={this.handleClick}>Click Me</button>;

}

}

   2、使用箭头函数

     (1)render中使用箭头函数

class ReactEvent extends Component {

handleClick() {

console.log('Click');

}

render() {

return <button onClick={() => this.handleClick()}>Click Me</button>;

} }

(2)使用class fields语法

   class ReactEvent extends Component {

//此函数会被绑定到ReactEvent类的实例

handleClick = () => {

console.log('Click');

}

render() {

return <button onClick={this.handleClick}>Click Me</button>;

} }

    (3)在render中使用bind

class ReactEvent extends Component {

handleClick() {

console.log('Click');

}

render() {

return <button onClick={this.handleClick.bind(this)}>Click Me</button>;

} }

   二、几种方式比较

影响

constructor函数中bind

使用class fields语法

render中使用箭头函数

在render中使用bind

render时生成新函数

性能

无影响

无影响

有影响

有影响

可直接携带参数

简洁性

不好

 

三、事件处理中传参

  在开发当中,经常遇到对一个列表做操作,可能包含删除,修改,查看。这时候绑定事件就需要传参,通常为id。

   1、直接传递参数

 

 

  2、使用data属性

    

例如:

import React, { Component } from "react";

export default class EventComponet extends Component {
    constructor(props) {
        super(props);
        this.state= {
            list: [
                {
                    id: 1,
                    msg: 'AAA'
                },
                {
                    id: 2,
                    msg: 'BBB'
                },
                {
                    id: 3,
                    msg: 'CCC'
                }
            ]
        }
    }
    handleClick(e) {
        console.log(e.target.dataset.id)
    }
    render() {
        const { list } = this.state
        return (
            <div>
                {
                    list.map(item=><button data-id={ item.id } key={ item.id} onClick={this.handleClick}>{item.msg}</button>)
                }
            </div>
        )
    }
}

这里不强制推荐使用哪一种,对于各个团队来说,可以根据项目,选择自己团队的事件绑定方式。

因为箭头函数的简洁性,在公司项目中,通常使用class fields 定义箭头函数来绑定事件。当需要传参的时,单个参数传递使用data属性传参。多个参数传递时,采用拆分子组件的方式回调传参。

上一篇:java面试题-2.容器之Map


下一篇:React学习笔记(四)--- 组件通讯