2
votes

liaison d'action mobx react

Pour ceux qui ont écrit des applications avec mobx + react , je me demande s'il existe un meilleur moyen de gérer les problèmes de contexte (par exemple, ceci.

/ code> renvoie undefined dans le magasin mobx ) lors de l'utilisation du gestionnaire d'événements onClick dans un composant react w / inject & observateur .

J'ai écrit le gestionnaire comme onClick = {actionFromStore.bind (this.props.theStore)} pour résoudre ce problème, mais il semble qu'il devrait y avoir un moyen plus concis de le faire que Je ne suis pas au courant.

Je ne suis pas un expert de mobx, tout conseil serait apprécié!

Les actions ici sont des requêtes de récupération asynchrone


0 commentaires

3 Réponses :


4
votes

Vous pouvez utiliser le décorateur @ action.bound :

@action
doSomething = ()=> {

    // logic

}

ou utiliser la fonction labmda qui préservera le contexte:

@action.bound
doSomething(){

    // logic

}


1 commentaires

Cela ressemble plus à ce que je cherchais, je vais le tester et vérifier cette réponse si cela fonctionne. Merci!



3
votes

Depuis 2018, la meilleure pratique dans le développement d'applications React consiste à utiliser des fonctions lambda comme propriétés de classe au lieu de méthodes de classe.

La fonction lambda en tant que propriété de classe résout tous les problèmes qui peuvent survenir avec le contexte. Vous n'avez pas à lier les méthodes au contexte spécifique, si vous l'utilisez.

Par exemple, vous travaillez avec this dans une méthode de classe:

export default class SomeClass {
    myProp = "kappa"

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

Dans ce cas, si vous l'utilisez, par exemple, comme certains écouteurs d'événements, ce sera de manière inattendue (en fait, plus que prévu) changer de SomeClass instance à une autre valeur. Donc, si vous utilisez des méthodes de classe, vous devez modifier votre code comme ceci:

export default class SomeClass {
    myProp = "kappa"

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

Dans le constructeur, vous liez votre méthode de classe au contexte de SomeClass

La meilleure façon d'éviter ce type de code inutile (imaginez que vous ayez plus de 10 méthodes de ce type - et que vous devriez lier chacune d'elles), est simplement d'utiliser des fonctions lambda:

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

    myProp = "kappa"

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

Voilà! Les fonctions Lambda n'ont pas de contexte, donc ceci pointera toujours vers l'instance SomeClass . Donc, maintenant vous pouvez décorer votre propriété de classe comme vous le souhaitez:

export default class SomeClass {
    myProp = "kappa"

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

Notez que si vous utilisez Babel, vous devez utiliser transform-class-properties plugin.

Cette question est plus liée au cœur de JavaScript, je vous conseille donc de lire cet article MDN pour plus d'informations sur ce comportement.

J'espère que ceci a été utile!


3 commentaires

Je connais JS this . Mais je pense que mon problème est plus lié à mobx + react . Voyons si je peux reproduire le problème lorsque j'en ai l'occasion


Les problèmes de contexte @BiYoo sont toujours liés à vanilla-JS;) Le problème que vous avez décrit pourrait survenir même si vous utilisiez un autre combo de bibliothèques (par exemple RxJS + React ou mobx + Vue , etc.)


Vous aviez raison, c'était la fonction async que j'avais pensé l'utiliser comme fonction anonyme dans le magasin mobx . C'était en effet vanilla JS qui causait ce comportement. Le simple fait d'utiliser bound dans la bibliothèque mobx a résolu le problème (j'aurais pu utiliser la fonction lambda mais en utilisant bound lire plus concis et compréhensible dans notre base de code ). Merci!



0
votes

Avec Mobx 6, les décorateurs sont de plus en plus découragés et encombrants à utiliser (obligeant makeObservable (this) à être appelé soigneusement dans le constructeur, même dans les sous-classes.)

Je le trouve donc maintenant plus propre à utiliser

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

plutôt que

@action.bound
doStuff() { ...

ou

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

Ce modèle sans décorateur également fonctionne dans les anciennes versions de Mobx.


0 commentaires