Pour ceux qui ont écrit des applications avec / code> renvoie J'ai écrit le gestionnaire comme 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 mobx
+ react
, je me demande s'il existe un meilleur moyen de gérer les problèmes de contexte (par exemple, ceci.
undefined
dans le magasin mobx
) lors de l'utilisation du gestionnaire d'événements onClick
dans un composant react w / inject
& observateur
. 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.
3 Réponses :
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 }
Cela ressemble plus à ce que je cherchais, je vais le tester et vérifier cette réponse si cela fonctionne. Merci!
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!
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!
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.