MobX自动运行和构造函数内部的反应

时间:2017-10-19 13:09:52

标签: javascript reactjs mobx autorun

自动运行反应必须在构造函数中才能工作吗? 我可以在没有构造函数的情况下编写这个简单的例子吗?

我在自动运行中的代码也正常运行但如果我将其更改为console.log(this.expenses)则无效。那是为什么?

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

1 个答案:

答案 0 :(得分:1)

自动运行反应不必在构造函数中。例如,如果您愿意,可以这样做:

示例

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)
)

console.log(`${this.expenses}`)工作原因而console.log(this.expenses)不起作用的原因是因为在编写this.expenses时,您没有在浅层数组中取消引用任何内容。

当你写...

`${this.expenses}`

...您隐含在toString()上致电this.expenses。您可以使用toJSslice在不将其放入字符串时获得相同的效果:

示例(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)