我一直试图通过MobX,React,TypeScript和动作来获得看起来像一个简单的例子,但却无法做到。没有严格,一切正常,但我宁愿使用严格模式。
我得到的错误是:
Uncaught Error: [mobx] 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: AppState@1.timer
at invariant (mobx.module.js:2704)
at fail$1 (mobx.module.js:2699)
at checkIfStateModificationsAreAllowed (mobx.module.js:3303)
at ObservableValue.prepareNewValue (mobx.module.js:997)
at ObservableObjectAdministration.write (mobx.module.js:1093)
at AppState.set [as timer] (mobx.module.js:1257)
at AppState.set [as timer] (mobx.module.js:143)
at new AppState (index.tsx:26)
at eval (index.tsx:66)
不幸的是,我不知道我应该把@action(或@ action.bound)放在哪里使它工作,或者我做错了什么......
这是我的代码:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import * as MobX from 'mobx';
import * as MobXReact from 'mobx-react';
import DevTools from 'mobx-react-devtools';
MobX.configure({
enforceActions: 'strict'
});
class AppState {
@MobX.observable
public timer = 0;
public constructor() {
setInterval(() => {
this.incrTimer();
}, 1000);
}
@MobX.action
public incrTimer() {
this.timer += 1;
}
@MobX.action
public resetTimer() {
this.timer = 0;
}
}
@MobXReact.observer
class TimerView extends React.Component<{appState: AppState}, {}> {
render() {
return (
<div>
<button onClick={this.onReset}>
Seconds passed: {this.props.appState.timer}
</button>
<DevTools/>
</div>
);
}
onReset = () => {
this.props.appState.resetTimer();
}
};
const appState = new AppState();
const rootNode = document.body.appendChild(document.createElement('div'));
ReactDOM.render(<TimerView appState={appState} />, rootNode);
更新:根据答案进行了更多的修改后,发现错误来自TS发出的JS。 TS public timer = 0;
在this.timer = 0;
内constructor
发出了schedule
属性,这正在爆发。
删除赋值并添加另一个函数已经超出了错误,但是对于属性初始化这样做似乎不应该是必要的。
答案 0 :(得分:1)
问题很可能是你在构造函数中设置了计时器。在构造函数完成之前,MobX不会包装您的属性,因此当构造函数设置此计时器回调时,它会获得对真实incrTimer的引用,而不是mobx.action(incrTimer)。如果将计时器安装移动到构造函数之外的方法,然后在构造对象后调用它,则此严格警告将消失。例如:
const appState = new AppState();
appState.setupTimer();