Reputation: 1821
I am struggeling to setup my project correctly to get rid of the mobx error when running in useStrict(true)
Error
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: [email protected]
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)
My setup compiles but the error is still there, so there must be a mistake in my build chain.
I have used the information provided from the GitHub repo here, but its all a bit vague.
.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];
};
I have tried the awesome typescript loader and also the ts-loader, babel-loader combo.
And here my store (short version)
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();
As soon as i call wikiStore.getTags() from a React component i get the error. Everything just works fine without useStrict(true)
(as expected)
Maybe someone has an idea.
Upvotes: 1
Views: 990
Reputation: 2053
Please read here: https://mobx.js.org/best/actions.html#async-await
As a result, @action only applies to the code block until the first await
So const tags = await Api.getTags();
must be wrapped again
@action
public async getTags() {
const tags = await Api.getTags();
runInAction(() => {
this.tags = tags;
})
}
Upvotes: 0
Reputation: 112887
I think you still need to split up the await
and the assignment:
@action
public async getTags() {
const tags = await Api.getTags();
this.tags.replace(tags);
}
Upvotes: 0