使用Typescript异步/等待函数和@action装饰器的mobx-deep-action

时间:2017-08-25 15:50:29

标签: reactjs typescript mobx mobx-react

我正在努力设置我的项目,以便在useStrict(true)

中运行时摆脱mobx错误

错误

mobx.module.js:2238 Uncaught (in promise) 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: WikiStore@1.tags
    at invariant (mobx.module.js:2238)
    at fail (mobx.module.js:2233)
    at checkIfStateModificationsAreAllowed (mobx.module.js:2794)
    at ObservableValue.prepareNewValue (mobx.module.js:750)
    at setPropertyValue (mobx.module.js:1605)
    at WikiStore.set [as tags] (mobx.module.js:1575)
    at WikiStore.<anonymous> (WikiStore.tsx:25)
    at step (tslib.es6.js:91)
    at Object.next (tslib.es6.js:72)
    at fulfilled (tslib.es6.js:62)

我的设置编译但错误仍然存​​在,因此我的构建链中一定有错误。

我使用了GitHub回购here提供的信息,但它有点模糊。

.babelrc

{
"passPerPreset": true,
"presets": [
    {
        "plugins": ["transform-regenerator"]
    },
    {
        "plugins": ["mobx-deep-action"]
    },
    {
      "plugins": ["babel-plugin-transform-decorators-legacy"]
    },
    "es2015", "react", "stage-0"
]
}

webpack.config.js

const path = require("path");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const webpack = require("webpack");
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;

const clientBundleOutputDir = "./wwwroot/dist";

module.exports = (env) => {

    const clientConfig = {
        stats: { modules: false },
        entry: { "main-client": "./Client/index.tsx" },
        resolve: { extensions: [".js", ".jsx", ".ts", ".tsx" ] },
        output: {
            filename: "[name].js",
            path: path.join(__dirname, clientBundleOutputDir),
            publicPath: "/dist/"
        },
        module: {
            rules: [
                { test: /\.s?css$/, use: ["css-hot-loader"].concat(ExtractTextPlugin.extract({fallback: "style-loader", use: ["css-loader", "sass-loader"]})) },
                { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
                { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" },
                { test: /\.(png|svg|jpg|gif|ico)$/, use: ["file-loader"] },
                // { test: /\.tsx?$/, include: /Client/, use: "awesome-typescript-loader?silent=true&useBabel=true&useCache=true" }
                { test: /\.tsx?$/, include: /Client/, use: ["babel-loader", "ts-loader"] }
            ]
        },
        plugins: [
            new CheckerPlugin(),
            new ExtractTextPlugin("site.css"),
            new webpack.SourceMapDevToolPlugin({
                filename: "[file].map",
                moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]')
            })
        ]
    };

    return [clientConfig];
};

我尝试了很棒的打字机加载程序以及ts-loader,babel-loader组合。

这是我的商店(简短版)

import { autorun, observable, action } from "mobx";
import { Wiki } from "../models/Wiki";
import { Tag } from "../models/Tag";
import * as Api from "../api/api";

export class WikiStore {
    @observable public tags: Tag[] = [];

    constructor() {
        this.getTags();
    }

    @action
    public async getTags() {
        this.tags = await Api.getTags();
    }
}

export const wikiStore = new WikiStore();

一旦我从React组件调用wikiStore.getTags(),我就会收到错误。没有useStrict(true)(正如预期的那样)

,一切正常

也许有人有个主意。

2 个答案:

答案 0 :(得分:0)

我认为您仍然需要拆分public static MyListFragment newInstance(ArrayList<Integer> list1,ArrayList<Integer> list2) { MyListFragment myListFragment = new MyListFragment(); Bundle bundle = new Bundle(); bundle.putIntegerArrayList("oki", list1); bundle.putIntegerArrayList("okiquantitapizze", list2); myListFragment.setArguments(bundle); return myListFragment; } 和作业:

        MyListFragment myFragment = MyListFragment.newInstance(list1,list2);
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.a, myFragment);
        transaction.commit();

答案 1 :(得分:0)

请在这里阅读: https://mobx.js.org/best/actions.html#async-await

  

因此,@action只适用于代码块,直到第一次等待

所以const tags = await Api.getTags();必须再次换行

@action
public async getTags() {
    const tags = await Api.getTags();
    runInAction(() => {
      this.tags = tags;
    })
}