V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
NicholasNC
V2EX  ›  问与答

React, ES6 语法出现的一个疑惑

  •  
  •   NicholasNC · 2016-06-22 19:40:56 +08:00 · 2258 次点击
    这是一个创建于 3108 天前的主题,其中的信息可能已经有所发展或是发生改变。
    import React, {Component} from 'react';
    
    export default class AddBtn extends Component {
        render() {
            return (
                <button onClick={function() {
                    this.handleClick();
                }}>
                    Add
                </button>
            )
      }
    
      handleClick() {
        this.props.onAddClick();
      }
    }
    
    import React, {Component} from 'react';
    
    export default class AddBtn extends Component {
        render() {
            return (
                <button onClick={() => this.handleClick()}>
                    Add
                </button>
            )
      }
    
      handleClick() {
        this.props.onAddClick();
      }
    }
    

    说明,上述两段代码中this.props.onAddClick();是从父组件中传递进来的,工能只是控制台输出一个f

    第一段代码中,用了ES5 的语法,但是报错,如下图:

    第二段代码中,用了ES6 的箭头语法,运行正确,如下图:

    问题来了
    这两个写法是不是一样的吗?(就算我在第一种写法中加行一个return this.handleClick();结果还是报错)

    我猜
    会不会是和 ES6 的块作用域有关?

    11 条回复    2016-06-23 08:06:29 +08:00
    FrankFang128
        1
    FrankFang128  
       2016-06-22 19:42:59 +08:00
    去年都有人写文章科普了。两个写法的 this 是不一样的。
    hvsy
        2
    hvsy  
       2016-06-22 19:43:18 +08:00 via iPhone
    箭头语法会自动绑定 this 指针的,随意箭头语法更普通的 function 是不一样的
    Twinkle
        3
    Twinkle  
       2016-06-22 19:48:29 +08:00
    ES6 写法的话, React component 非自带的函数 this 并不指向自身,需要用 bind(this) 来绑定
    onClick={this.handleClick.bind(this)}
    NicholasNC
        4
    NicholasNC  
    OP
       2016-06-22 19:54:17 +08:00
    一言惊醒梦中人。用古老的这种写法也可以。
    render() {
    let self = this;
    return (
    <button onClick={function() {
    return self.handleClick();
    }}>
    Add
    </button>
    )
    }

    不过还有一点不是很能理解,
    () => this.handleClick();转换成 ES5 就是上述代码,但是那个 return 凑什么热闹,一个事件处理函数返回一个执行结果好像没什么意义(虽然这样写也没错)
    kiscall
        5
    kiscall  
       2016-06-22 20:40:34 +08:00 via Android
    第一种写法的 this 指向 button ,而 button 没有 handleClick 方法,所以怎么写都报错。 es6 的那个写法 this 指向 component ,就能访问到 handleClick 方法。 NicholasNC 的方法拿到了全局指针,所以又能访问到 handleClick 方法了。
    EPr2hh6LADQWqRVH
        6
    EPr2hh6LADQWqRVH  
       2016-06-22 20:43:56 +08:00
    我了个去。。。

    真受不了代码里面混写标签。。。
    bdbai
        7
    bdbai  
       2016-06-22 20:46:57 +08:00 via Android
    请善用调试器。在执行代码那一行下个断点,观察右边显示的 this 你就明白了。
    sox
        8
    sox  
       2016-06-22 21:16:06 +08:00
    既然你知道是 arrow function 为什么不知道为什么。。
    zhangxiao
        9
    zhangxiao  
       2016-06-22 21:20:04 +08:00
    @avastms jsx 还行,不像 php 那种混法。
    hvsy
        10
    hvsy  
       2016-06-22 21:20:42 +08:00 via iPhone
    @NicholasNC 箭头函数是为了方便快捷的简写,所以它当这个函数只有一条语句的时候就会将这条一句作为返回值,这样可以很方便的兼容各种情况
    NicholasNC
        11
    NicholasNC  
    OP
       2016-06-23 08:06:29 +08:00
    @sox 其实我对 ES6 也是一知半解,之前粗略看过阮一峰的教程 http://es6.ruanyifeng.com ,虽然有看过箭头函数自动绑定 this ,不过真正用起来还是被 ES5 的想法套住了,编程遇坑才对一些知识点更深刻。 O(∩_∩)O 哈!

    @hvsy 那其实 return self.handleClick(); 和 self.handleClick();在这里也就没什么区别?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2508 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 15:53 · PVG 23:53 · LAX 07:53 · JFK 10:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.