简体   繁体   English

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

[英]Mobx changing observable values outside of action

I'm getting the following error:我收到以下错误:

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>

But I am wrapping the function in an action so I'm a little confused:但是我将函数包装在一个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服务.js

// ...

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

What am I missing here?我在这里缺少什么?

A function that alters the observables needs to be wrapped in action , so use it on the callback as well:一个改变 observables 的函数需要被包装在action ,所以也可以在回调中使用它:

getAllTodos: action(() => {

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

As stated in the MobX docs here :正如此处的 MobX 文档所述:

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!这意味着如果您有 setTimeout、promise.then 或异步构造,并且在该回调中更改了更多状态,则这些回调也应包含在 action 中!

Thus, you'd have to wrap the scheduled promise.then here in an action as well, apart from the parent function.因此,除了父函数之外,您还必须将预定的promise.then包装在一个操作中。 (Note that you'd only be able to use the @action on the class-level function) (请注意,您只能在类级函数上使用@action

There are two ways of doing it:有两种方法可以做到:

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

--or-- ——或——

Use the @action.bound :使用@action.bound

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM