美文网首页React
React进阶-事件处理

React进阶-事件处理

作者: Galette_LJ | 来源:发表于2019-04-04 16:56 被阅读0次

    React元素的事件处理和 DOM元素的很相似。但是有一点语法上的不同:

    !React事件绑定属性的命名采用驼峰式写法,而不是小写

    !如果采用 JSX的语法,你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM元素的写法)

    // 传统的HTML

    <button onclick="clickFun()">
        点击按钮
    </button>

    // React 语法

    <button onClick={clickFun}>
        点击按钮
    </button>

    !在 React中另一个不同的是,你不能使用返回 false的方式阻止默认行为。你必须明确的使用preventDefault。

    // 传统的 HTML中阻止链接默认打开一个新页面

    <a href="#" onclick="console.log('这个链接被点击了。'); return false">
        点我
    </a>

    // React 语法

    function ActionLink () {
        function handleClick (e) {
            e.preventDefault();
            console.log('The link was clicked.');
        }

        return (
            <a href="#" onClick={handleClick}>
                点我
            </a>
        );
    }

    使用 React的时候通常不需要你使用 addEventListener 为一个已创建的 DOM元素添加监听器。你仅仅需要在这个元素初始渲染的时候提供一个监听器。

    当你使用 ES6 class 语法来定义一个组件的时候,事件处理器会成为类的一个方法。例如,下面的 Toggle组件渲染一个让用户切换开关状态的按钮:

    class Toggle extends React.Component {

        constructor (props) {
            super (props);
            this.state = {isToggleOn: true};
            this.handleClick = this.handleClick.bind(this);
        }

        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')
    );

    你必须谨慎对待 JSX 回调函数中的 this,类的方法默认是不会绑定 this的。如果你忘记绑定this.handleClick 并把它传入 onClick,当你调用这个函数的时候 this的值会是 undefined。

    这并不是 React的特殊行为;它是函数如何在 JavaScript中运行的一部分。通常情况下,如果你没有在方法后面添加 (),例如 onClick = {this.handleClick}, 你应该为这个方法绑定 this。

    如果使用 bind 让你很烦,这里有两种方式可以解决。如果你正在使用实验性的属性初始化语法,你可以使用属性初始化器来正确的绑定回调函数:

    // 这个语法在 Create React App 中默认开启。

    class LoggingButton extends React.Component {

        handleClick = () => {
            console.log('this is:', this);
        }

        render () {
            <button onClick={this.handleClick}>
                点我
            </button>
        }

    }

    如果你没有使用属性初始化器语法,你可以在回调函数中使用 箭头函数:

    class LoggingButton extends React.Component {
        handleClick () {
            console.log('this is:', this);
        }  

        render () {
            return (
                <button onClick={ (e) => this.handleClick(e) }>
                    点我    
                </button>
            );
        }

    }

    使用这个语法有个问题就是每次 LoggingButton 渲染的时候都会创建一个不同的回调函数。在大多数情况下,这没有问题。然而如果这个回调函数作为一个属性值传入低阶组件,这些组件可能会进行额外的重新渲染。

    我们通常建议在 构造函数汇中绑定 或 使用属性初始化器语法 来避免这类性能问题。

    向事件处理程序传递参数

    通常我们会为事件处理程序传递额外的参数。

    例如,若是 id是你要删除那一行的id,以下两种方式都可以向事件处理函数传递参数:

    <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
    <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

    上述两种方式是等价的,分别通过 arrow functions 和 Function.prototype.bind 来为事件处理函数传递参数。

    上面两个例子中,参数 e作为 React事件对象将会被作为第二个参数进行传递。通过箭头函数的方式,事件对象必须显式的进行传递,但是通过 bind的方式,事件对象以及更多的参数将会被隐式的进行传递。

    值得注意的是,通过 bind方式向监听函数传参,在类组件中定义的监听函数,事件对象 e要排在所传递参数的后面,例如:

    class Popper extends React.Component {

        constructor () {
            super ();
            this.state = {name: 'Hello world!'};
        }

        preventPop (name, e){   //事件对象 e要放在最后
            e.preventDefault();
            alert(name);
        }

        render (){
            return (
                <div>
                    <p>hello</p>
                    <a href="https://reactjs.org"  onClick={this.preventPop.bind(this,this.state.name)}></a>
                </div>
            )
        }

    }

    参考网址:

    事件处理—React

    相关文章

      网友评论

        本文标题:React进阶-事件处理

        本文链接:https://www.haomeiwen.com/subject/kjoruqtx.html