Reputation: 529
Support for the experimental syntax 'decorators-legacy' isn't currently enabled
I tried adding the decorators-legacy
babel plugin and @babel/plugin-proposal-decorators
with { legacy: true }
in .babelrc
but no effect.
Anyone managed to get MobX decorators to work with CRA2?
Upvotes: 15
Views: 14594
Reputation: 79
If you use babel 7 you have to add some config in babelrc. Install support for decorators:
npm i --save-dev @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators
And enable it in your .babelrc file:
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true}],
["@babel/plugin-proposal-class-properties", { "loose": true}]
]
}
or you can use MobX built-in utility like:
import { observable, computed, action, decorate } from "mobx";
class Timer {
start = Date.now();
current = Date.now();
get elapsedTime() {
return this.current - this.start + "milliseconds";
}
tick() {
this.current = Date.now();
}
}
decorate(Timer, {
start: observable,
current: observable,
elapsedTime: computed,
tick: action
});
I had the same problem and I used mobx-utility and every thing completely worked for me.
Upvotes: 2
Reputation: 953
You don’t have to use more packages, or change configurations.
1- Use decorate in stores – for observable, computed :
import { observable, decorate } from "mobx"
class ToDoStore {
todos= ["cat","dog"]
}
decorate(ToDoStore, {
todos: observable,
});
const store = new ToDoStore()
2- For observer – use the follow class style:
import React from "react"
import { observer } from "mobx-react"
const TodoList = observer(class TodoList extends React.Component {
render() {
const {todos} = this.props.store;
const todoL = todos.map(todo => (<li>{todo}</li>))
return (
<div>
<h1>ToDo List</h1>
<ul>{todoL}</ul>
</div>
);
}
})
export default TodoList
Upvotes: 2
Reputation: 5054
Option 1: Using decorators with CRA v2
If you refer to Mobx documentation, you can get Mobx decorators to work with CRAv2 by using Typescript:
Decorators are only supported out of the box when using TypeScript in create-react-app@^2.1.1.
However, in some cases, you might still face issues when using Mobx with other react frameworks. In that case:
Option 2: Don't use decorators
A detailed step by step guide is documented here.
If you previously defined your observer react component as:
@observer
export default class MyComponent extends React.Component
Change it to:
const MyComponent = observer(class MyComponent extends React.Component{
/* ... */
});
export default MyComponent;
If you previously had:
@observable myElement = null;
You need to change it to:
myElement;
then:
decorate(MyComponent, {
myElement: observable,
})
Hope this helps!
Upvotes: 4
Reputation: 422
I did an example project of React App 2.0 with Babel 7 and Mobx(with decorators works) without eject! :
Links I used to create this project:
https://github.com/timarney/react-app-rewired/issues/348
https://github.com/arackaf/customize-cra#addbabelpluginsplugins
https://www.leighhalliday.com/mobx-create-react-app-without-ejecting
Upvotes: 3
Reputation: 18672
Firstly, install dependencies:
yarn add react-app-rewired customize-cra @babel/plugin-proposal-decorators
Secondly, create config-overrides.js
in root directory with following contents:
const {
addDecoratorsLegacy,
override,
disableEsLint
} = require("customize-cra");
module.exports = {
webpack: override(
addDecoratorsLegacy(),
disableEsLint()
)
};
You should be able to use mobx + decorators now.
If you don't have mobx installed already, please run:
yarn add mobx mobx-react
.
Now you can use decorators.
Upvotes: 7
Reputation: 111
although others answers are correct if you want to avoid boilerplate code, It's possible to use decorators in CRA2 without ejecting using https://github.com/timarney/react-app-rewired/ and https://github.com/arackaf/customize-cra
Upvotes: 1
Reputation: 495
While using CRA2, in order to use MOBX5 you must do following.
npm install -save mobx mobx-react
Now add following lines in your store file.
import {decorate, observable} from "mobx"
import {observer} from "mobx-react"
Now you can use something like this.
class Store {
//...
}
decorate(Store, {
list: observable
})
const appStore = new Store()`
Upvotes: 1
Reputation: 15464
I had same issue and ended up with using mobx4 where Decorators can be used without decorator syntax.
class Store {
//...
@action empty() {
this.data = []
}
@action add(e) {
this.data.push(e)
}
}
can be rewritten as
class Store {
//...
empty() {
this.data = []
}
add(e) {
this.data.push(e)
}
}
decorate(Store, {
add: action,
empty: action
})
You can use this feature out of the box from CRA2 and do not need to worry about transform decoracy plugin. Thanks Michel Weststrate for this stuff
https://medium.com/@mweststrate/mobx-4-better-simpler-faster-smaller-c1fbc08008da
Upvotes: 4
Reputation: 483
npm run eject
Add the bold line to /config/webpack.config.dev.js around line 162. Make sure to do the same on /config/webpack.config.prod.js otherwise the app won’t build
plugins: ["@babel/plugin-proposal-decorators", { "legacy": true }],
Upvotes: -1