2017-10-19 5 views
2

Sie Autorun und Reaktion innerhalb des Konstruktor sein müssen, um zu arbeiten? Kann ich dieses einfache Beispiel ohne Konstruktor schreiben?MobX Autorun und Reaktion innerhalb Konstruktor

Auch der Code, den ich in der Autorun haben läuft normal, aber wenn ich es console.log(this.expenses) ändern funktioniert es nicht. Warum das?

import { observable, action, computed, useStrict, autorun, reaction } from 'mobx' 
useStrict(true) 

class ExpensesStore { 

    @observable.shallow expenses = [] 

    @action addExpense = (expense) => { 
    this.expenses.push(expense) 
    } 

    @computed get getExpense() { 
    if(this.expenses.length > 0) { 
     return `This is computed from ${this.expenses[0] + this.expenses[1]}` 
    } 

    } 


    constructor() { 
    autorun(() => { 
     console.log(`${this.expenses}`) 
    }) 

    reaction(
    ()=>this.expenses.map(expense => expense), expense => console.log(expense) 
    ) 
    } 


} 

const store = window.store= new ExpensesStore() 

export default store 

Antwort

1

Autorun und Reaktion muss nicht im Konstruktor sein. Sie könnten dies zum Beispiel tun, wenn Sie bevorzugen:

Beispiel

class ExpensesStore { 
    @observable.shallow expenses = [] 

    @action addExpense = (expense) => { 
    this.expenses.push(expense) 
    } 

    @computed get getExpense() { 
    if(this.expenses.length > 0) { 
     return `This is computed from ${this.expenses[0] + this.expenses[1]}` 
    } 
    } 
} 

const store = new ExpensesStore() 

autorun(() => { 
    console.log(`${store.expenses}`) 
}) 

reaction(
() => store.expenses.map(expense => expense), expense => console.log(expense) 
) 

Der Grund, warum console.log(`${this.expenses}`) Werke und console.log(this.expenses) nicht, weil Sie nichts in Ihrem flachen Array dereferencing wenn Sie this.expenses schreiben.

Wenn Sie schreiben ...

`${this.expenses}` 

... Sie fordern implizit toString() auf this.expenses. Sie können toJS oder slice verwenden, um die gleiche Wirkung zu erhalten, wenn es nicht in einem String setzen:

Beispiel (JSBin)

class ExpensesStore { 
    @observable.shallow expenses = [] 

    @action addExpense = (expense) => { 
    this.expenses.push(expense) 
    } 

    @computed get getExpense() { 
    if(this.expenses.length > 0) { 
     return `This is computed from ${this.expenses[0] + this.expenses[1]}` 
    } 
    } 
} 

const store = new ExpensesStore() 

autorun(() => { 
    // store.expenses.slice() works just as well 
    console.log(toJS(store.expenses)) 
}) 

reaction(
() => store.expenses.map(expense => expense), expense => console.log(expense) 
) 

setTimeout(() => { 
    store.addExpense(1000) 
}, 1000) 
+1

Thx Tholle. Ich sehe meinen Fehler in Anbetracht von console.log. Wenn also Autorun und Reaktion keine Dekoratoren benötigen und außerhalb des Klassen-Ausgabenspeichers leben können, kann ich sie herausnehmen, sie in eine andere Komponente einfügen und sie von dort aus ausführen. Gibt es eine Möglichkeit, Maßnahmen zu ergreifen und zu berechnen? Ich möchte eine Struktur ähnlich wie Redux machen, wo ich Aktionen in einer Datei haben könnte, in einer anderen speichern? –

+0

@ Igor-Vuk Kein Problem! Absolut, MobX ist sehr flexibel. Ich würde die Berechnungen für die Klassen in diesem Fall persönlich behalten, aber die Aktionen verschieben. Ich habe das selbst vor nicht allzu langer Zeit in einem Projekt gemacht und es fühlte sich an wie eine nette, veränderbare Version von Redux. – Tholle

+0

Wie würde ich das tun, die Aktionen ausführen und sie aus einer anderen Datei versenden? Ich habe eine andere Frage gestellt, wenn Sie mitmachen möchten. https://stackoverflow.com/questions/46840028/structure-mobx-project-like-redux Ich werde diese Antwort als eine Lösung für meine erste Frage akzeptieren. Danke. –

Verwandte Themen