MobX не обновляет DOM, реагируя на обратный вызов обещания fetch

Я пытаюсь обновить реагирующий дом, изменив наблюдаемую переменную mobx внутри обратного вызова fetch в приложении react typescript, но mobx не показывает никакой реакции на изменение переменной. Я определяю свою переменную следующим образом:

@observable  data:any = []

и в моем конструкторе я меняю значение данных:

 constructor(){
        this.data.push(
            {
                count:0,
                dateTime:'2017'
            })
        this.getData();
    }

он работает нормально и обновляет dom должным образом, как и ожидалось. в методе getData() я пишу выборку для получения данных с сервера:

@action getData(){
   this.data.push(
     {
      count:1,
      dateTime:'2018'
     })
    fetch(request).then(response=>response.json())
    .then(action((data:Array<Object>)=>{
        this.data.push(data)
        console.log(data)
    }));
}

поэтому мое представление теперь показывает 2 значения данных объекта 2017 и 2018 годов, но данные 2019 года, которые я получаю с сервера, не отображаются. журнал показывает правильные значения и переменную, заполненную правильным образом, но mobx не обновляет представление после того, как я установил любую переменную в обратном вызове функции выборки, и я не знаю, почему? p.s: я делаю то же самое в ECMA и проблем не было, но в typescript mobx действуют по-другому


person javad bat    schedule 21.07.2018    source источник
comment
Ваш компонент является наблюдателем?   -  person mweststrate    schedule 21.07.2018
comment
Я не уверен, что это отвечает на вопрос. Он имел в виду, есть ли в вашем компоненте декоратор @observer?   -  person kingdaro    schedule 21.07.2018
comment
Я думаю, вам нужно будет предоставить для этого минимальный воспроизводимый пример.   -  person    schedule 23.07.2018
comment
Проблема не в мобксе. Mobx не несет ответственности за обновление представления. Так что либо реагировать, либо mobx-реагировать. Вы сказали, что использовали @observer, так что проблема может быть на стороне React. Возможно, вы неправильно установили значение ключа для компонента при сопоставлении значений. Это может привести к неправильному отображению реакции. Без дополнительного кода трудно сказать.   -  person Kev    schedule 23.07.2018
comment
Попробуйте вместо того, чтобы вставлять в наблюдаемый, попробуйте скопировать массив, добавив значение в копию и присвоив его обратно наблюдаемому const data = [...this.data]; data.push(data); this.data = data; `   -  person Edward Chopuryan    schedule 27.07.2018


Ответы (2)


Проверьте мой подход:

import { action, observable, runInAction } from 'mobx'

class DataStore {
  @observable data = null
  @observable error = false
  @observable fetchInterval = null
  @observable loading = false

  //*Make request to API
  @action.bound
  fetchInitData() {
    const response = fetch('https://poloniex.com/public?command=returnTicker')
    return response
  }

  //*Parse data from API
  @action.bound
  jsonData(data) {
    const res = data.json()
    return res
  }

  //*Get objects key and push it to every object
  @action.bound
  mapObjects(obj) {
    const res = Object.keys(obj).map(key => {
      let newData = obj[key]
      newData.key = key
      return newData
    })
    return res
  }

  //*Main bound function that wrap all fetch flow function
  @action.bound
  async fetchData() {
    try {
      runInAction(() => {
        this.error = false
        this.loading = true
      })
      const response = await this.fetchInitData()
      const json = await this.jsonData(response)
      const map = await this.mapObjects(json)
      const run = await runInAction(() => {
        this.loading = false
        this.data = map
      })
    } catch (err) {
      console.log(err)
      runInAction(() => {
        this.loading = false
        this.error = err
      })
    }
  }

  //*Call reset of MobX state
  @action.bound
  resetState() {
    runInAction(() => {
      this.data = null
      this.fetchInterval = null
      this.error = false
      this.loading = true
    })
  }

  //*Call main fetch function with repeat every 5 seconds
  //*when the component is mounting
  @action.bound
  initInterval() {
    if (!this.fetchInterval) {
      this.fetchData()
      this.fetchInterval = setInterval(() => this.fetchData(), 5000)
    }
  }

  //*Call reset time interval & state
  //*when the component is unmounting
  @action.bound
  resetInterval() {
    if (this.fetchInterval) {
      clearTimeout(this.fetchInterval)
      this.resetState()
    }
  }
}

const store = new DataStore()
export default store

person jocoders    schedule 21.08.2019

как @mweststrate упоминал в комментариях, это была проблема наблюдателя, и когда я добавляю @observer поверх моего класса реакции, проблема исправляется

person javad bat    schedule 28.07.2018
comment
Итак, когда вы упомянули в вопросе «у моего компонента есть @observer», на самом деле его не было? - person JJJ; 28.07.2018
comment
да, но это и про @action.bound. Я не пробовал их обоих вместе, за упоминание - person javad bat; 30.07.2018