2

I am writing a function in React JSX which contains callbacks that need to talk to 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
        });
    });

Notice the this.state.washedMissions? When I am inside that callback, the Firefox script debugger shows me that the browser doesn't know what this is and thus I can't manipulate my arrays this way.

How can I ensure that this is within the scope of my callback -- and note, the callback is synchronous, so I am not worried about any timing stuff.

4

3 回答 3

3

你有

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

您需要提供Array.prototype.forEachthisArg作为第二个参数

...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() {}

或者你需要一个在词法上绑定值的箭头函数this

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

Function.prototype.bind或者您可以使用其他答案中提供的石器时代慢

于 2015-11-05T03:21:54.323 回答
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
    });
});
于 2015-11-05T03:32:22.753 回答
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));
    
于 2015-11-05T03:08:54.617 回答