MobX State Tree Generator не позволяет модифицированное состояние в успешном обещании? - PullRequest
0 голосов
/ 14 ноября 2018

Через следующий код я получаю эту ошибку:

error: Error: [mobx-state-tree] Cannot modify 
'AuthenticationStore@<root>', the object is protected and can only be 
modified by using an action.

код (генератор), о котором идет речь:

.model('AuthenticationStore', {
    user: types.frozen(),
    loading: types.optional(types.boolean, false),
    error: types.frozen()
  })
  .actions(self => ({
    submitLogin: flow(function * (email, password) {
      self.error = undefined
      self.loading = true
      self.user = yield fetch('/api/sign_in', {
        method: 'post',
        mode: 'cors',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          'user' : {
            'email': email,
            'password': password
          }
        })
      }).then(res => {
        return res.json()
      }).then(response => {
        self.loading = false // the error happens here!
        return response.data
      }).catch(error => {
        console.error('error:', error)
        // self.error = error
      })
    }), ...

Вопрос: это не так?разрешено в генераторе, есть ли лучший способ обновить это конкретное состояние или его нужно обернуть при помощи try / catch?

Как всегда спасибо заранее за любые отзывы!

1 Ответ

0 голосов
/ 16 ноября 2018

Проблема в том, что вы вызываете then в Обещании, возвращаемом fetch(), а функция, которую вы передаете then, не является действием.Обратите внимание, что функции, которые запускают в действии (или потоке), не считаются самим действием.

Поскольку вы используете yield, вам не нужно вызывать then или catch на Обещании, возвращенном fetch().Вместо этого оберните это в попытку / поймать:

submitLogin: flow(function * (email, password) {
  self.error = undefined;
  self.loading = true;
  try {
    const res = yield fetch('/api/sign_in', {
        method: 'post',
        mode: 'cors',
        headers: {
        'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          'user' : {
            'email': email,
            'password': password
          }
        })
    });
    const response = yield res.json();
    self.loading = false;
    self.user = response;
  } catch(error) {
    console.log('error: ', error);
    self.error = error;
  }
}
...