React not rerendering после смены наблюдателя mobx

После загрузки страницы я вижу "hi2". Когда я нажимаю кнопку, ничего не происходит. Я тоже пробовал с setUser.

Я подозреваю, что я просто редактирую сами реквизиты, и почему-то наблюдаемое не запускается?

См. Пример кода, который не работает здесь, в совершенно новой среде rails / react: https://github.com/bufordtaylor/mobxtest

  1. клон
  2. пучок
  3. рельсы s
  4. (в другом процессе) ./bin/webpack-dev-server --host 127.0.0.1
  5. перейдите на localhost: 3000

======================

ОБНОВИТЬ:

Я сократил его до базовой формы, исключив возможные ошибки импорта, ошибки поставщика или ошибки конструктора.

Вот

import React from 'react'
import ReactDOM from 'react-dom'
import { observable, action, computed } from 'mobx';
import { Provider, inject, observer } from 'mobx-react';


class UserStore {

  @action setUser(val) {
    console.log(val);
    this.user = val;
  }

  @observable user = "default";
}

const userStore = new UserStore();

@observer
class Hello extends React.Component {
  render() {
    return (
      <div>
        hi2 {this.props.userStore.user}
        <button onClick={this.props.userStore.setUser.bind(this,"fwefwe")}>faew</button>
      </div>
    )
  }
}

document.addEventListener('DOMContentLoaded', () => {
  ReactDOM.render(
    <Hello userStore={userStore} />,
    document.getElementById('app'),
  )
})

person wiznaibus    schedule 01.10.2017    source источник
comment
У меня работает. Вы можете понять, что в вашем случае отличается?   -  person Tholle    schedule 01.10.2017
comment
Не повезло. Я скопировал ваш код прямо в свой редактор. @ Толле.   -  person wiznaibus    schedule 01.10.2017
comment
Это раздражает. Единственное, что кажется мне немного подозрительным, - это import UserStore from '../bundles/User/stores/UserStore';. ../bundles/User/stores/UserStore предполагаемый импорт?   -  person Tholle    schedule 01.10.2017
comment
Я подумал об этом после того, как увидел твой код. Но после того, как я буквально скопировал / вставил ваш код в один большой файл, он по-прежнему работает, как описано ранее. В настоящее время я загружаю новое приложение, чтобы проверить его там.   -  person wiznaibus    schedule 01.10.2017
comment
В вопрос добавлено новое приложение rails / response. Ваш код копируется прямо в app/javascript/packs/hello_react.jsx файл @tholle. К сожалению, та же проблема.   -  person wiznaibus    schedule 01.10.2017
comment
Облом. Не могли бы вы поставить transform-decorators-legacy первым в списке плагинов babel?   -  person Tholle    schedule 01.10.2017
comment
Я сошел с ума по этой проблеме. Я сгорбился над ноутбуком вчера с 16:00, почти не спал, выпил слишком много кофе, огрызнулся на жену и, наконец ... У меня есть решение. Спасибо, @Tholle!   -  person wiznaibus    schedule 01.10.2017


Ответы (6)


Ваш код выглядит надежным. Я думаю, вы наткнулись на проблему, обсуждаемую в Как (не) использовать декораторы часть документации. Важно, чтобы transform-decorators-legacy был первым в списке плагинов babel.

person Tholle    schedule 01.10.2017
comment
Недавно я столкнулся с этой проблемой при использовании сборщика посылок. Это связано с ошибкой в ​​посылке, которая неправильно анализирует файлы tsconfig.json. См. здесь. - person Adam Mazzarella; 01.02.2019

Моя проблема заключалась в порядке упаковки компонента, потому что я использовал фреймворк Material UI.

Неправильно:

export inject('store')(observer(withStyles(styles)(MyComponent)));

Верно:

export withStyles(styles)(inject('store')(observer(MyComponent)));

Итак, важен порядок с MobX и React Material UI.

person Alin Ciocan    schedule 22.05.2018
comment
Ты спасаешь мою жизнь - person user3896501; 31.10.2019
comment
@ArjunTRaj, возможно, что-то еще возится с Mobx. Попробуйте использовать только инъекцию и наблюдатель в компоненте и посмотрите, не в этом ли проблема. Иначе могло быть что-то другое. Я обнаружил, что если вы не читаете данные из магазина в компоненте, рендеринг не запускается. - person Alin Ciocan; 26.11.2019

если вы используете последнюю версию mobx и babel версии 7.12, добавьте это в конструктор

makeObservable(this)
person tarik203    schedule 11.11.2020
comment
Спасибо. меня устраивает. Но у вас опечатка. Это должно быть makeObservable(this) - person hakiko; 07.12.2020
comment
спасибо я поправлю :) - person tarik203; 08.12.2020
comment
Вы спасли меня!!! - person Chen Ni; 30.01.2021
comment
Я так счастлив, что нашел этот ответ, спасибо! - person Piotr Sobuś; 15.02.2021
comment
Кто-нибудь еще сталкивался с ошибкой, когда магазин наблюдается в локальной среде, но не в производственной среде? Решил эту проблему, прикрепив наблюдателя к дочерним компонентам, но я не уверен, что это было спроектировано таким образом. - person mymoto; 14.04.2021
comment
Это сработало! Однако почему декоратор @observer больше не работает? Он даже не выдает предупреждения ... (версии: [email protected], [email protected] - я заметил, что декоратор @observer больше не работает после обновления с mobx 5 до 6 сегодня) - person Venryx; 24.07.2021
comment
Хорошо, я нашел ответ: mobx.js.org/enpting-decorators.html Проблема заключалась не в @observer декораторе классов, а в декораторе @observable field - теперь для применения декораторов полей требуется вызов внутри конструктора. (подробности см. по ссылке выше) - person Venryx; 24.07.2021

<button onClick={this.props.userStore.setUser.bind(this,"fwefwe")}>faew</button>

Будь осторожен. Вы связываете this. This в данном случае является экземпляром компонента Hello. Теперь this в функции setUser указывает на компонент Hello. Таким образом, setUser установит свойство user в компоненте Hello.

 @action setUser(val) {
    console.log(val);
    this.user = val; // This this now points to the Hello Component.
  }

Чтобы понять, что я имею в виду, вы можете установить точку останова в методе setUser, а затем проверить переменную this. Вы увидите, что он указывает на компонент Hello, а не на экземпляр вашего магазина.

Вместо этого сделайте следующее:

<button onClick={() => { this.props.userStore.setUser("fwefwe"); }}>faew</button>

Здесь я создаю лямбду, которая вызывает setUser в пользовательском хранилище. Поскольку здесь я использую лямбду, this в this.props.userStore указывает на компонент Hello.

person Daniel    schedule 01.10.2017

Для всех, кто приезжает сюда, убедитесь, что вы не такой полный идиот, как я, и не забыли добавить декоратор @observer перед компонентом класса.

(Или декоратор @observable в магазине)

Боже, потратил на это целый день

person jonyB    schedule 21.07.2020
comment
Вы не одиноки, я также забыл обернуть свой функциональный компонент функцией наблюдателя. 10к + репутация ... ничего не значит :) - person shift66; 18.02.2021

У меня была аналогичная проблема, я использовал функцию стрелки для метода рендеринга:

render = (): React.ReactNode

правильно должно быть:

render(): React.ReactNode

до сих пор не уверен, почему первый случай смущает mobx.

person Ivan    schedule 30.04.2020