Mobx在行动之外改变可观察的价值观

时间:2017-10-29 08:49:46

标签: javascript reactjs ecmascript-6 mobx

我收到以下错误:

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/');
}

我在这里缺少什么?

2 个答案:

答案 0 :(得分:7)

改变observable的函数需要包含在action中,所以也要在回调中使用它:

getAllTodos: action(() => {

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

答案 1 :(得分:2)

如MobX文档here中所述:

动作包装器/装饰器仅影响当前正在运行的功能,而不影响当前功能调度(但未调用)的功能!这意味着,如果您具有setTimeout,promise.then或async结构,并且在该回调中更改了更多状态,则这些回调也应包含在动作中!

因此,除了父函数之外,您还必须在一个动作中包装计划的promise.then。 (请注意,您只能在类级函数上使用@action

有两种方法可以做到:

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

-或-

使用@action.bound

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

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