Mobx React никогда не обновляется

Я пытаюсь понять реализацию mobx в React. Я использовал create response app и обновил конфигурацию по умолчанию, чтобы использовать декораторы. Затем я создал такой простой магазин:

РЕДАКТИРОВАТЬ: после ответа Бена Хейра (спасибо ему!) Я обновил свой код следующим образом:

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import MessageStore from "./store/messages";

ReactDOM.render(<App store={new MessageStore()} />, 
document.getElementById('root'));

** App.js **

import React from "react";
import { observer } from "mobx-react";

@observer
export default class App extends React.Component {

    constructor(props) {
        super(props);
        this.store = props.store;
    }

    render() {
        return <ul>
            { this.store.allMessages.map((msg) => {
                return <li key={msg}>{msg}</li>
            })}
        </ul>
    }
}

messages.js

import {action, observable, computed} from "../../node_modules/mobx/lib/mobx";

export default class MessageStore {

    @observable messages = ["My first message"];

    constructor() {
        setInterval(() => {
            // Add some random messages every second
            this.addMessage(Math.random());
        }, 1000);
    }

    @action addMessage(msg) {
        this.messages.push(msg);
    }

    @computed get allMessages() {
        return this.messages;
    }

}

Отображается первое сообщение, но компонент никогда не обновляется, когда setInterval добавляет сообщение в хранилище. Вы можете мне помочь ?


person Somebody    schedule 21.06.2017    source источник
comment
Как вы визуализируете свой простой компонент? В mobx вам нужно передать хранилище в качестве опоры, чтобы @observer работал, вы не можете просто получить к нему доступ внутри рендера. Это не приведет к повторной визуализации при изменении.   -  person Ben Hare    schedule 21.06.2017
comment
Спасибо за ответ @BenHare Я отредактировал свой вопрос   -  person Somebody    schedule 21.06.2017


Ответы (2)


Работает для меня:

https://codesandbox.io/s/LgQXNBnNW

Вы видели какие-либо ошибки в журнале браузера или в терминале?

person mweststrate    schedule 21.06.2017
comment
Спасибо за ответ и за то, что нашли время протестировать мой код! Это работает, поэтому я проверил разницу между вашим и моим кодом, и моя ошибка заключалась в следующем: меня заманила моя IDE! Я заменил: import {action, observable, computed} из ../../node_modules/mobx/lib/mobx; путем импорта {действие, наблюдаемое, вычисленное} из mobx; и он отлично работает - person Somebody; 21.06.2017

Проверьте мой подход, пожалуйста. Может, поможет: Магазин MobX:

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