Mobx React动作绑定

6
对于那些使用 mobx + react 编写应用程序的人,我想知道在使用 injectobserver 的 react 组件中使用 onClick 事件处理程序时如何更好地处理上下文问题(例如,在 mobx 存储中,this. 返回 undefined)。
我一直像这样编写处理程序:onClick={actionFromStore.bind(this.props.theStore)} 来解决这个问题,但似乎应该有更简洁的方法,我不知道。
我不是 mobx 专家,任何建议都将不胜感激!
这里的操作是异步获取请求。
3个回答

7

你可以使用@action.bound装饰器:

@action.bound
doSomething(){

    // logic

}

或者使用保留上下文的lambda函数:

@action
doSomething = ()=> {

    // logic

}

1
这看起来更像是我在寻找的东西,我会测试一下并检查是否有效。谢谢! - Bi Yoo

4

自从2018年以来,React应用程序开发的最佳实践是使用lambda函数作为类属性而不是类方法。

将lambda函数作为类属性可以解决所有可能出现的上下文问题。如果使用它,您不必将方法绑定到特定上下文。

例如,您正在某个类方法中使用this

export default class SomeClass {
    myProp = "kappa"

    myMethod() {
        console.log(this.myProp)
    }
}

在这种情况下,如果您将其用作事件侦听器等,this 将意外地(实际上比预期更多)从 SomeClass 实例更改为其他值。因此,如果您使用类方法,则应将代码修改为以下内容:

export default class SomeClass {
    constructor() {
        this.myMethod = this.myMethod.bind(this)
    }

    myProp = "kappa"

    myMethod() {
        console.log(this.myProp)
    }
}

在构造函数中,您正在将类方法绑定到SomeClass实例的上下文中。
避免这种不必要的代码的最佳方法(想象一下,您有10个以上的这种方法 - 您应该绑定每个方法),就是简单地使用lambda函数。
export default class SomeClass {
    myProp = "kappa"

    myMethod = () => {
        console.log(this.myProp)
    }
}

就是这样!Lambda函数没有上下文,因此this始终会指向SomeClass实例。所以,现在您可以根据自己的需要装饰类属性:

export default class SomeClass {
    myProp = "kappa"

    @action
    myMethod = () => {
        console.log(this.myProp)
    }
}

请注意,如果您使用Babel,则必须使用transform-class-properties插件。
这个问题与JavaScript的核心更相关,因此我建议您阅读MDN文章以了解更多关于this行为的信息。
希望这有所帮助!

我知道 JS this。但我认为我的问题更与 mobx + react 相关。让我看看我是否有机会重现这个问题。 - Bi Yoo
@BiYoo 上下文问题总是与纯JS有关;) 即使您使用其他库组合(例如RxJS + Reactmobx + Vue等),您描述的问题也可能发生。 - Limbo
1
你说得对,我确实是将 async 函数误以为是匿名函数在 mobx 存储中使用了。实际上是普通的 JS 导致了这种行为。只需在 mobx 库中使用 bound 就可以解决这个问题(虽然我本可以使用 lambda 函数,但是在我们的代码库中使用 bound 更加简洁易懂)。谢谢! - Bi Yoo

3

在 Mobx 6 中,已经不鼓励使用装饰器,并且在使用时会变得更加繁琐(甚至需要小心地在构造函数中调用 makeObservable(this),即使是在子类中也是如此)。

因此,我现在觉得更清晰的做法是使用:

doStuff = action(() => {
    //  stuff logic
})

相较于

@action.bound
doStuff() { ...

或者

@action
doStuff = () => { ...

在较旧的 Mobx 版本中,没有装饰器的这种模式也可以使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接