在React JSX

时间:2015-11-05 03:06:58

标签: javascript scope reactjs react-jsx arrow-functions

我在React JSX中编写一个函数,其中包含需要与this交谈的回调

    this.socket.on('addWashedMission', washedMission => {
        console.log('onAddWashedMission - %s - %s', washedMission.name, 
            new Date(washedMission.birthtime));

        this.state.washedMissions.filter(function(o) {
            return o.name === washedMission.name;
        }).forEach(function(element, i, arr) {
            // HERE IT IS //
            this.state.washedMissions.state.washedMissions.slice(
                this.state.washedMissions.state.washedMissions.indexOf(element), 1);
        });

        this.state.washedMissions.push(washedMission);
        this.state.washedMissions.sort(function(a,b) {
            return b.birthtime - a.birthtime;
        });

        this.setState({
            washedMissions: this.state.washedMissions
        });
    });

注意this.state.washedMissions?当我在回调中时,Firefox脚本调试器向我显示浏览器不知道this是什么,因此我无法以这种方式操纵我的数组。

如何确保this在我的回调范围内 - 注意,回调是同步的,所以我不担心任何计时。

3 个答案:

答案 0 :(得分:3)

你有

...forEach(function(element, i, arr) {
  this.state.washedMissions.state.washedMissions.slice(
    this.state.washedMissions.state.washedMissions.indexOf(element), 1);
});

您需要提供thisArg作为Array.prototype.forEach

的第二个参数
...forEach(function(element, i, arr) {
  this.state.washedMissions.state.washedMissions.slice(
    this.state.washedMissions.state.washedMissions.indexOf(element), 1);
}, this); // <--- note the `this` after the function() {}

或者你需要一个arrow function词汇绑定this

...forEach((element, i, arr) =>
  this.state.washedMissions.state.washedMissions.slice(
    this.state.washedMissions.state.washedMissions.indexOf(element), 1)
);

或者您可以使用其他答案中提供的石头年龄慢Function.prototype.bind

答案 1 :(得分:2)

为所有功能使用更多箭头功能

this.socket.on('addWashedMission', washedMission => {
    console.log('onAddWashedMission - %s - %s', washedMission.name, 
        new Date(washedMission.birthtime));

    this.state.washedMissions
        .filter(o => {
            return o.name === washedMission.name;
        })
        .forEach((element, i, arr) => {
            const elementIndex = this.state.washedMissions.state.washedMissions.indexOf(element);
            this.state.washedMissions.state.washedMissions.slice(elementIndex, 1);
        });

    this.state.washedMissions.push(washedMission);
    this.state.washedMissions.sort((a,b) => {
        return b.birthtime - a.birthtime;
    });

    this.setState({
        washedMissions: this.state.washedMissions
    });
});

答案 2 :(得分:1)

问题是匿名函数范围内的this不会引用定义它的包含范围。它将引用它所分配的对象的范围,以及稍后从中调用它的范围。

因此,您需要“欺骗”它以使this引用您想要的this

有几种方法可以达到你想要的效果。

  1. 在匿名函数之外使用var that = this;定义,并在其中引用它而不是this来创建闭包。 (旧版浏览器的向后兼容性更好)

    var that = this;
    this.state.washedMissions.filter(function(o) {
        return o.name === washedMission.name;
    }).forEach(function(element, i, arr) {
        // HERE IT IS //
        that.state.washedMissions.state.washedMissions.slice(
            that.state.washedMissions.state.washedMissions.indexOf(element), 1);
    });
    
  2. 将匿名函数的范围绑定到其定义范围的this,然后将其传递给forEach方法(用于处理此问题的首选ECMA5方法)

    this.state.washedMissions.filter(function(o) {
        return o.name === washedMission.name;
    }).forEach(function(element, i, arr) {
        // HERE IT IS //
        this.state.washedMissions.state.washedMissions.slice(
            this.state.washedMissions.state.washedMissions.indexOf(element), 1);
    }.bind(this));