• React文档(七)处理事件


    React元素处理事件和DOM元素处理事件很类似。下面是一些语法的不同之处:

    • React事件的命名是用驼峰命名,而不是小写字母。
    • 利用JSX你传递一个函数作为事件处理器,而不是一个字符串。

    举个例子,这是一段HTML:

    <button onclick="activateLasers()">
      Activate Lasers
    </button>

    而在React中略微有些不同:

    <button onClick={activateLasers}>
      Activate Lasers
    </button>

    另一个不同之处就是在React中你不能通过返回false来阻止事件默认的行为。你必须调用preventDefault。举个例子,一个简单的页面,为了阻止默认的链接行为打开一个新页面,你可以这样写:

    <a href="#" onclick="console.log('The link was clicked.'); return false">
      Click me
    </a>

    在React中就得这样写:

    function ActionLink() {
      function handleClick(e) {
        e.preventDefault();
        console.log('The link was clicked.');
      }
    
      return (
        <a href="#" onClick={handleClick}>
          Click me
        </a>
      );
    }

    在这里,e是一个综合的事件。React通过W3C标准来定义这些综合事件,所以你可以不用担心跨浏览器兼容性问题。看看SyntheticEvent手册学习更多知识。

    当使用React你通常不需要调用addEventListener来向一个被创建的DOM元素添加事件监听器。只需要当元素首次被渲染的时候提供一个监听器。

    当你使用ES6的类定义了一个组件,一个相同的模式就是一个事件监听器会是类的一个方法。举个例子,这个Toggle组件渲染了一个按钮来让用户在打开和关闭的状态中来回变化:

    class Toggle extends React.Component {
      constructor(props) {
        super(props);
        this.state = {isToggleOn: true};
    
        // This binding is necessary to make `this` work in the callback
        this.handleClick = this.handleClick.bind(this);
      //bind方法会将函数handleClick的this设置为提供的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') );

    在CodePen中试一试

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

    这并不是React的特殊行为;而是函数如何在js中工作的一部分。通常,如果你涉及到了一个后面没有()的方法,就像onClick={this.handleClick},你应该为那个函数调用bind方法改变它的this。

    如果调用bind使你厌烦,还有两种方法可以避免使用bind。如果你使用实验性的属性初始化语法,你可以使用属性初始化来正确地绑定回调:

    class LoggingButton extends React.Component {
      // This syntax ensures `this` is bound within handleClick.
      // Warning: this is *experimental* syntax.
      handleClick = () => {
        console.log('this is:', this);
      }
    
      render() {
        return (
          <button onClick={this.handleClick}>
            Click me
          </button>
        );
      }
    }

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

    如果你不使用属性初始化语法,你可以在回调里使用箭头函数:

    class LoggingButton extends React.Component {
      handleClick() {
        console.log('this is:', this);
      }
    
      render() {
        // This syntax ensures `this` is bound within handleClick
        return (
          <button onClick={(e) => this.handleClick(e)}>
            Click me
          </button>
        );
      }
    }
    这个语法的问题就是当LoggingButton组件每一次渲染的时候一个不同的回调函数就会被创建。在大多数情况下,这没有什么问题。然而,如果这个回调函数被当做一个props传递给子组件,那么那些子组件可能会做一次重新渲染。我们通常建议将方法在构造函数里绑定一下this或者使用属性初始化语法,这样可以避免这一类重复创建的问题。
    向事件处理程序传递参数
    通常我们会为事件处理程序传递额外的参数。例如,若是 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>
                    {/* Pass params via bind() method. */}
                    <a href="https://reactjs.org" onClick={this.preventPop.bind(this,this.state.name)}>Click</a>
                </div>
            );
        }
    }
  • 相关阅读:
    Asp.Net 获取客户端真实IP方法总结
    C# 中英文符号互转(半角全角互转)
    执行git commit命令提示: “Please tell me who you are”的解决方案
    Tools
    VSC
    DevOps
    VSC
    DevOps
    DevOps
    K8S
  • 原文地址:https://www.cnblogs.com/hahazexia/p/6385750.html
Copyright © 2020-2023  润新知