15

MobX 2.2.2 を使用して、非同期アクション内で状態を変更しようとしています。MobX の useStrict を true に設定しています。

@action someAsyncFunction(args) {
  fetch(`http://localhost:8080/some_url`, {
    method: 'POST',
    body: {
      args
    }
  })
  .then(res => res.json())
  .then(json => this.someStateProperty = json)
  .catch(error => {
    throw new Error(error)
  });
}

私は得る:

Error: Error: [mobx] Invariant failed: It is not allowed to create or change state outside an `action` when MobX is in strict mode. Wrap the current method in `action` if this state change is intended

2 番目の .then ステートメントに @action デコレータを指定する必要がありますか? どんな助けでも大歓迎です。

4

3 に答える 3

20

2 番目の .then ステートメントに @action デコレータを指定する必要がありますか? どんな助けでも大歓迎です。

これは実際のソリューションにかなり近いです。

.then(json => this.someStateProperty = json)

する必要があります

.then(action(json => this.someStateProperty = json))

actionに限定されない多くの方法で呼び出すことができることに注意してください@actiondocs on actionから:

  • action(fn)
  • action(name, fn)
  • @action classMethod
  • @action(name) classMethod
  • @action boundClassMethod = (args) => { body }
  • @action(name) boundClassMethod = (args) => { body }

関数をアクションとしてマークするすべての有効な方法です。

ソリューションを示すビンは次のとおりです。http://jsbin.com/peyayiwowu/1/edit?js,output

mobx.useStrict(true);
const x = mobx.observable(1);

// Do async stuff
function asyncStuff() {
  fetch('http://jsonplaceholder.typicode.com/posts')
    .then((response) => response.json())
    // .then((objects) => x.set(objects[0])) BREAKS
    .then(mobx.action((objects) => x.set(objects[0])))
}

asyncStuff()

エラーが実際に発生する理由については、最上位@actionが装飾している関数内のアクションとして関数を再帰的に装飾していないと推測しています。つまり、promise に渡された匿名関数は実際にはaction.

于 2016-05-31T20:47:49.940 に答える
10

上記の回答を補足するために; 実際、action渡した関数でのみ機能します。の関数はthen別のスタックで実行されるため、別のアクションとして認識できる必要があります。

アクションに名前を付けることもできるので、それらを使用する場合に devtools で簡単に認識できることに注意してください。

then(action("update objects after fetch", json => this.someStateProperty = json))

于 2016-05-31T21:02:41.067 に答える