J. Reku
J. Reku

Reputation: 529

How to get MobX Decorators to work with Create-React-App v2?

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

Answers (9)

Zahra Hajilary
Zahra Hajilary

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

Citizen-Dror
Citizen-Dror

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

Arial
Arial

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

Almog_0
Almog_0

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

Daniel
Daniel

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

landbit
landbit

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

Junaid Atique
Junaid Atique

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

sumit
sumit

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

I.dev
I.dev

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

Related Questions