React Mobx - компонент не обновляется после изменения магазина

При использовании Mobx после обновления магазина (т. Е. Нажатия кнопки) компонент не перерисовывается. Я установил mobx devtools, который ничего не показывает после начальной загрузки, и в консоли нет ошибок. Есть идеи, что я сделал не так?

Store.js:

import { observable } from 'mobx';

class Store {

    @observable me;

    constructor() {
        this.me = 'hello';
    }

    change_me(){
        this.me = 'test 1234';

    }

}


export default Store;

layout.js:

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


@observer
export default class Layout extends React.Component{

    render(){

        return(
            <div>
                <h1>{this.props.store.me}</h1>
              <button onClick={this.on_change}>Change</button>
            </div>
        )
    }

    on_change = () => {
        this.props.store.change_me();
    }
}

index.js:

import React from "react";
import ReactDOM from "react-dom";
import Layout from "./components/Layout";
import Store from "./Store";
import DevTools, { configureDevtool } from 'mobx-react-devtools';

// Any configurations are optional
configureDevtool({
    // Turn on logging changes button programmatically:
    logEnabled: true,
    // Turn off displaying conponents' updates button programmatically:
    updatesEnabled: false,
    // Log only changes of type `reaction`
    // (only affects top-level messages in console, not inside groups)
    logFilter: change => change.type === 'reaction',
});


const app = document.getElementById('app');
const store = new Store();

ReactDOM.render(

    <div>
        <Layout store={store} />
        <DevTools />
    </div>
, app);

person Chris    schedule 20.11.2016    source источник
comment
Я копирую вставленный ваш код, и он работает в моей среде. after updating the store the component does not re-render значит после того, как кнопку щелкнешь правильно?   -  person Max    schedule 20.11.2016
comment
Ага, точно. Так это работает для вас? Что еще это может быть?   -  person Chris    schedule 20.11.2016
comment
Просто безумное предположение, проверьте свой каталог импорта, правильно он или нет.   -  person Max    schedule 20.11.2016
comment
Каталог импорта? Это могло бы привести к тому, что все приложение вообще не будет работать, не так ли? Приложение работает, только обновление после нажатия кнопки.   -  person Chris    schedule 20.11.2016
comment
@Chris, не могли бы вы сделать для этого jsfiddle?   -  person rab    schedule 20.11.2016
comment
Все это выглядит довольно стандартно. В вашем проекте включены декораторы? Может помочь скрипка (в readme mobx есть те же базовые скрипты, которые вы можете использовать в качестве базы) или тестовое репо. Вы проверяли журналы браузера на наличие исключений?   -  person mweststrate    schedule 20.11.2016
comment
Можете ли вы поделиться своей настройкой .babelrc?   -  person mweststrate    schedule 20.11.2016
comment
Вы читали это? Возможно, вам нужно будет поставить transform-decorators-legacy первым в вашем списке плагинов.   -  person Tholle    schedule 21.11.2016
comment
stackoverflow.com/questions/40702028/   -  person Eduard Jacko    schedule 27.04.2017
comment
Спасибо, @Tholle! Я уверен, что это сэкономило мне еще несколько часов разочарования :-)   -  person Sam A. Horvath-Hunt    schedule 10.08.2017
comment
@SamHH Отлично! Без проблем. :)   -  person Tholle    schedule 10.08.2017


Ответы (3)


Я бы начал с добавления @action к вашей функции change_me (). Насколько я понимаю, это не всегда требуется полностью, но я несколько раз сталкивался с подобными проблемами в моем собственном коде, когда забывал их добавить.

Кроме того, опубликуйте свой .babelrc как предложенный @mweststrate, так как это поможет другим проверить, загружены ли правильные плагины.

person cdoc    schedule 20.11.2016

Я предполагаю, что @observable был бы неинициализированным. Это очень нелогично, но Babel плохо справляется с этим. Даже добавление @observable me = undefined может помочь (см. Сгенерированный код js, когда вы что-то там назначаете. Обычно я бы полностью удалил конструктор и переместил инициализацию в объявление (т.е. @observable me = "hello" без конструктора). Тогда он должен работать нормально.

person Nopik    schedule 20.11.2016

Следите за привязкой этого контекста.

<button onClick={this.on_change}>Change</button>

эта ссылка не будет относиться к классу, поэтому, вероятно, когда вы на самом деле щелкаете, он скажет что-то вроде строки no props на undefined. Переход на:

  <button onClick={this.on_change.bind(this)}>Change</button>

должен это исправить. Или, еще лучше, привяжите контекст в конструкторе, чтобы он не привязывался к каждому рендерингу.

 constructor(props) {
   super(props)
   this.on_change = this.on_change.bind(this)
 }

тогда вы можете вернуться к своему

person dpastoor    schedule 20.11.2016
comment
Это очень неправильный ответ по двум причинам. Во-первых, on_change привязан к this, как он объявлен, так что оригинальный вызов {this.on_change} хорош. Тогда наличие .bind () внутри {} является анти-шаблоном, приводящим к снижению производительности, и его никогда не следует использовать. - person Nopik; 21.11.2016
comment
@Nopik Не совсем так. on_change не привязан к this. React автоматически связывает аналогичные методы, но только если компонент объявлен через createClass, а не при использовании классов ES6. - person Sulthan; 21.11.2016
comment
@Nopik, как говорит султан, вам действительно нужно прочитать свою привязку. Кроме того, как я демонстрирую ниже, правильным шаблоном является привязка в конструкторе. Вы также можете прочитать больше здесь: egorsmirnov.me/2015/ 16 августа / react-and-es6-part3.html - person dpastoor; 21.11.2016
comment
on_change уже привязан, потому что написано так: on_change = () => { ... }, что вызывает привязку во время создания экземпляра. Дополнительную информацию см. В предложении ES Public Class Fields. - person Thai; 22.11.2016
comment
@dpastoor 1) Султан ошибается, 2) в самой ссылке, которую вы опубликовали, указан метод, используемый в качестве метода 4, в качестве допустимого способа привязки к нему (просто еще не в стандарте, по-видимому, OP использует расширения) - person Nopik; 23.11.2016