Повторная отрисовка при асинхронной выборке с помощью react-mobx

Я пытаюсь использовать mobx-rest с mobx-rest-axios-adapter и mobx-react, и у меня возникли проблемы с повторной отрисовкой компонента при асинхронном извлечении данных.

Вот моя модель данных в state/user.js:

import { Model } from 'mobx-rest';

class User extends Model {
  url() {
    return '/me';
  }
}

export default new User();

Это компонент React в App.js:

import React from 'react';
import { inject, observer } from 'mobx-react';
import { apiClient } from 'mobx-rest';
import createAdapter from 'mobx-rest-axios-adapter';
import axios from 'axios';
import { compose, lifecycle, withProps } from 'recompose';

const accessToken = '...';
const API_URL = '...';

const App = ({ user }) => (
  <div>
    <strong>email:</strong>
    {user.has('email') && user.get('email')}
  </div>
);

const withInitialise = lifecycle({
  async componentDidMount() {
    const { user } = this.props;

    const axiosAdapter = createAdapter(axios);
    apiClient(axiosAdapter, {
      apiPath: API_URL,
      commonOptions: {
        headers: {
          Authorization: `Bearer ${accessToken}`,
        },
      },
    });

    await user.fetch();

    console.log('email', user.get('email'));
  },
});

export default compose(
  inject('user'),
  observer,
  withInitialise,
)(App);

Он использует перекомпоновку для асинхронного получения user из API в componentDidMount(), и, как только компонент станет доступным, он должен показать электронную почту пользователя. componentDidMount() печатает электронное письмо, когда оно становится доступным.

Наконец, это index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import createBrowserHistory from 'history/createBrowserHistory';
import { Provider } from 'mobx-react';
import { RouterStore, syncHistoryWithStore } from 'mobx-react-router';
import { Router } from 'react-router';

import App from './App';
import { user } from './state/user';

const documentElement = document.getElementById('ReactApp');

if (!documentElement) {
  throw Error('React document element not found');
}

const browserHistory = createBrowserHistory();
const routingStore = new RouterStore();

const stores = { user };
const history = syncHistoryWithStore(browserHistory, routingStore);

ReactDOM.render(
  <Provider {...stores}>
    <Router history={history}>
      <App />
    </Router>
  </Provider>,
  documentElement,
);

Моя проблема в том, что компонент не перерисовывается после того, как пользователь получен и электронная почта доступна, хотя журнал консоли показывает, что в асинхронном запросе он возвращается нормально. Я пробовал поиграть с computed mobx-react, но не повезло. Любые идеи?


person jorgen    schedule 01.09.2018    source источник


Ответы (1)


Думаю, это сработает, если вы измените порядок составления App.js:

export default compose(
  inject('user'),
  withInitialise,
  observer,
)(App);

Согласно официальному документу MobX,

Совет: когда наблюдатель необходимо объединить с другими декораторами или компонентами более высокого порядка, убедитесь, что наблюдатель является самым внутренним (применяемым первым) декоратором; в противном случае он мог бы вообще ничего не делать.

person Renwei Liu    schedule 03.09.2018
comment
Спасибо! Это должно быть проблемой. Я полагаю, что в моем случае это не работает с этим порядком, потому что withInitialise зависит от вещей, поставляемых observer. Но зная причину, я уверен, что смогу с этим разобраться. - person jorgen; 03.09.2018