无法使MobX,TypeScript,React和操作正常工作

时间:2018-04-19 01:50:32

标签: reactjs typescript mobx

我一直试图通过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属性,这正在爆发。

删除赋值并添加另一个函数已经超出了错误,但是对于属性初始化这样做似乎不应该是必要的。

1 个答案:

答案 0 :(得分:1)

问题很可能是你在构造函数中设置了计时器。在构造函数完成之前,MobX不会包装您的属性,因此当构造函数设置此计时器回调时,它会获得对真实incrTimer的引用,而不是mobx.action(incrTimer)。如果将计时器安装移动到构造函数之外的方法,然后在构造对象后调用它,则此严格警告将消失。例如:

const appState = new AppState();
appState.setupTimer();