Mobx 在动作之外改变可观察值

Mobx changing observable values outside of action

我收到以下错误:

proxyConsole.js:54 Error: [mobx] Invariant failed: Since strict-mode is enabled, changing observed observable values outside actions is not allowed. Please wrap the code in an `action` if this change is intended. Tried to modify: ObservableObject@1.items
    at invariant (mobx.module.js:2326)
    at fail (mobx.module.js:2321)
    at checkIfStateModificationsAreAllowed (mobx.module.js:2890)
    at ObservableValue../node_modules/mobx/lib/mobx.module.js.ObservableValue.prepareNewValue (mobx.module.js:796)
    at setPropertyValue (mobx.module.js:1673)
    at Object.set [as items] (mobx.module.js:1641)
    at Store.js:41
    at <anonymous>

但我将函数包装在 action 中,所以我有点困惑:

import { observable, useStrict, action } from 'mobx';
import Services from './Services';

// ...

getAllTodos: action(() => {

    Services.getAllTodos()
    .then((response) => {

        state.items = response.data;

    }).catch((error) => {
        console.error(error);
    });

}),

Services.js

// ...

getAllTodos () {
    return axios.get(root + '/items/');
}

我在这里错过了什么?

改变可观察对象的函数需要包装在 action 中,因此也可以在回调中使用它:

getAllTodos: action(() => {

  Services.getAllTodos()
  .then(action((response) => {
    state.items.replace(response.data);
  })).catch((error) => {
    console.error(error);
  });
})

如 MobX 文档所述here:

The action wrapper / decorator only affects the currently running function, not functions that are scheduled (but not invoked) by the current function! This means that if you have a setTimeout, promise.then or async construction, and in that callback some more state is changed, those callbacks should be wrapped in action as well!

因此,除了父函数之外,您还必须将预定的 promise.then 包装在一个操作中。 (请注意,您只能在 class-level 函数上使用 @action

有两种方法:

action(
  asyncFunction().then(
    action((args) => {
      // Your function body here
    })
  )
)

--或--

使用@action.bound:

@action
asyncFunction().then(
  yourStateModifyingFunction();
)

@action.bound
yourStateModifyingFunction() {
  // Your function body here
}