I am trying to get up and running with react create app and mobx state tree. I keep getting

Support for the experimental syntax 'decorators-legacy' isn't currently enabled (4:1):

I never used react create app so I am not sure how to enable, I tried making a .babelrc file but that did not help

{
    "presets": ["@babel/preset-env"],
    "plugins": [
        ["@babel/plugin-proposal-decorators", { "legacy": true }]
    ]
}


import React, { Component } from "react";
import { observer, inject } from "mobx-react";

@inject("domainStores")
@observer
export default class MainComponent extends Component {
  async componentDidMount() {}

  render() {
    return <div className="main-container">
            helllo

    </div>;
  }
}

I am also open to suggestions if things have changed, I have not used the newest version of Mobx State tree so many there is a better way of doing this now?

3

There are 3 answers

3
fazlu On BEST ANSWER

CRA does not allow you to extend your own configuration, so, in order to extend cra configuration, you will have to use customize-cra with react-app-rewired.

So, follow the steps below:

  1. Install customize-cra, react-app-rewired and @babel/plugin-proposal-decorators using npm or yarn
  2. add config-overrides.js at root level of your project and paste the code given below:
const {override, addDecoratorsLegacy } = require('customize-cra');
module.exports = override(addDecoratorsLegacy());
  1. Update package.json scripts to the below ones:
"start": "react-app-rewired start",
"build": "react-app-rewired build"

P.S: if you want to use babel configuration then your config-overrides.js should be like:

const {override, addDecoratorsLegacy, useBabelRc } = require('customize-cra');
module.exports = override(addDecoratorsLegacy(), useBabelRc());

useBabelRc will load config from your root of project automatically.

2
Tholle On

Instead of using the old decorators proposal, you can use observer as a function on your components instead of as a decorator.

We can also use React's own context instead of inject, as the documentation states:

Note: usually there is no need anymore to use Provider / inject in new code bases; most of its features are now covered by React.createContext.

This way we can use Create React App as is.

Example

import React from "react";
import { observer } from "mobx-react";
import { types } from "mobx-state-tree";

const StoresContext = React.createContext("store");

// custom hook that we can use in function components to get
// the injected store(s)
function useStore() {
  return React.useContext(StoresContext);
}

const StoreModel = types.model({
  things: types.array(types.string)
});
const storeInstance = StoreModel.create({ things: ["foo", "bar"] });

// instead of using the @observer decorator, we can use observer as
// a function and give it a component as argument
const MainComponent = observer(() => {
  const store = useStore();
  return (
    <div>
      {store.things.map((thing) => (
        <div key={thing}>{thing}</div>
      ))}
    </div>
  );
});

export default observer(function App() {
  return (
    <StoresContext.Provider value={storeInstance}>
      <MainComponent />
    </StoresContext.Provider>
  );
});
2
Danila On

If you only using MST without regular MobX stuff and only need inject and observer then you can use regular function syntax, it looks not that great, but does not require any setup:

export const WrappedComponent = inject("domainStores")(observer(Component)
// Or use export default here if you prefer

If you are using other features of MobX then in MobX 6 there is a new thing that will probably allow you to drop decorators (like computed, action and etc) altogether, makeAutoObservable:

import { makeAutoObservable } from "mobx"

class Store {
  // Don't need decorators now
  string = 'Test String';

  setString = (string) => {
    this.string = string;
  };

  constructor() {
    // Just call it here
    makeAutoObservable (this);
  }
}

With that you don't even need decorator syntax to be enabled.

More info here https://mobx.js.org/migrating-from-4-or-5.html and https://mobx.js.org/react-integration.html