【React整理系列】事件处理

【React整理系列】事件处理

一、React事件命名

不同于Vue,React的事件处理机制更加接近于原生事件的写法、

对于事件类型的指定,基本上是采用原生的写法(但是具体事件回调函数的指定有所不同):

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

即使用on+大写事件类型的形式

二、React事件参数:event对象

React中会默认传入event对象,这个event对象遵循W3C规范(也就是原生类似)

三、React阻止html元素的默认行为

在原生JavaScript中,如果要阻止元素的默认行为(比如说点击a标签默认打开链接),是在回调函数的最后
“`return false“`

但是在React,无法使用此方法,必须调用event对象中的
“`preventDefault“`方法

比如:

function ActionLink() {
    // 使用闭包指定对应回调函数
    function handleClick(e) {    
      e.preventDefault();    
      console.log('The link was clicked.');  
  }
    return (
    <a href="#" onClick={handleClick}>      Click me
    </a>
  );
}
四、在class组件和function组件中指定处理函数的通常格式
  • 在class组件中,我们通常将回调函数作为class对象的成员函数:

比如官方文档中这段代码:

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // 为了在回调中使用 `this`,这个绑定是必不可少的    this.handleClick = this.handleClick.bind(this);  }

  handleClick() {    
      this.setState(state => (
          {      
              isToggleOn: !state.isToggleOn    
          }));  
        }
  render() {
    return (
      <button onClick={this.handleClick}>        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);

需要注意的有如下几点:

  1. 所有的handleClick,在外面使用的时候都必须是以this.handleClick的形式进行调用,表示调用的handleClick是当前class的成员函数.

  2. 由于JavaScript的回调函数机制,class定义的回调方法,在回调的时候,是不绑定this的(也就是说,回调的时候的this,是undefinded),关于这点,我们可以试试添加以下打印函数进行尝试:

    class Link extends React.Component {
           constructor(props) {
               super(props);
               // 不给回调函数绑定this
               // this.handleClick = this.handleClick.bind(this);
           }
           handleClick(event) {
               //回调时候返回值应该是undefinded
               console.log("不绑定this,进行回调函数的时候:")
               console.log(this);
               // console.log(event);
               event.preventDefault();
               alert("clicked a ");
           };
           render() {
               // 非回调的时候
               console.log("非回调,在类中:")
               console.log(this);
               return (
                   <div>
                       <a href="xgpax.top" onClick={this.handleClick}>aaaa</a>
                   </div>
               );
           }
       }
       ReactDOM.render(<Link />, document.getElementById("app"));
    

​ 显示结果:

​ 很明显,我们可以看到回调函数中的this指向为undefined,所以我们需要给回调函数指定this,而这个指定方法,就是function.bind()方法(指定bind这种方法,其实不推荐使用,下文的推荐也只是一种相对而言)。

​ 有两种指定方法:

    1. 在调用时指定(不推荐)
<a href="xgpax.top" onClick={this.handleClick.bind(this)}>aaaa</a>
  1. 在constructor时指定(推荐)
constructor(props) {
            super(props);
            // 给回调函数绑定this
            this.handleClick = this.handleClick.bind(this);
        }

而现代化的写法,我们在第五点中讲(由于react hooks,class组件也不是很常用了)

  • 函数式组件的事件绑定机制:
// 函数式事件处理
    function Link() {
        let test = 1;
        function handleClick(event) {
            console.log(event);
            // 尝试打印test 证明可以使用闭包外的变量
            console.log(test); // 1 打印成功
            // 用来阻止默认事件的触发
            event.preventDefault();
            alert("clicked a!")
        };
        return (
            <div>
                <a href="xgpax.top" onClick={handleClick}>aaaa</a>
            </div>
        );
    }

在这里需要看到的是,函数内部没有this指针,所以没有上述困扰(由于react hooks,函数式逐渐已经成为主流)

我们采用闭包的方法来定义回调函数,由于闭包的变量机制,也就不会出现变量指向问题。

五、class组件使用ES6的箭头函数来绑定事件:

使用 bind 很麻烦,我们可以利用箭头函数与上层共享this的方法来解决,这里有两种方式可以解决:

  1. 在定义事件的回调函数的时候,使用箭头函数,然后在箭头函数内部定义要执行的方法(可以指定自己需要指定的参数)
    class LoggingButton extends React.Component {
     handleClick() {
       console.log('this is:', this);
     }
    
     render() {
       // 此语法确保 `handleClick` 内的 `this` 已被绑定。    
         return (      
         <button onClick={() => this.handleClick()}>        Click me
         </button>
       );
     }
    }
    
  2. 将回调函数修改为箭头函数的形式,用
    “`变量名=()=>{}“`

    的形式进行定义(create-react-app默认使用这种形式,主流)。

    class LoggingButton extends React.Component {
     // 此语法确保 `handleClick` 内的 `this` 已被绑定。
    handleClick = () => {    
                console.log('this is:', this);  
           }
     render() {
       return (
         <button onClick={this.handleClick}>
           Click me
         </button>
       );
     }
    }
    
六、react回调函数事件的传参

显然,默认的event事件无法解决所需要的所有情景,而使用类似小程序中data-set的形式又不够现代,且繁琐。

我们有如下指定方式:

  1. 还是利用es6箭头函数语法
    <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
    
  2. 利用bind进行传参
    <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
    

在这两种情况下,React 的事件对象 e 会被作为第二个参数传递。如果通过箭头函数的方式,事件对象必须显式的进行传递,而通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇