How to setup Mobx with react context
Tags: codingtutorials, devresources, javascript, react
Published: 2020-06-30 15:56:45

---
title: How to setup Mobx with react context
published: true
date: 2020-06-29 16:40:40 UTC
tags: CodingTutorials,Devresources,Javascript,React
canonical_url: https://codingislove.com/setup-mobx-react-context/
---

[Mobx](https://mobx.js.org/README.html) is a [Javascript](https://codingislove.com/tag/javascript/) library for state management. It is not specific to react but works great with react. Let’s see how to setup Mobx with react and react context specifically.

![Mobx react context example](https://codingislove.com/wp-content/uploads/2020/06/mox-react-context-demo-1024x500.png)

## What is react context?

Context provides a way to pass data through the component tree without having to pass props down manually at every level.

In simple words, React context is used to store some data at one place and use it all over the app. Components also re-render every time the data in context is modified. If we don’t use context then we would be passing data manually using props.

Technically, Mobx and other state management libraries also do the same thing but with more features

## Why use Mobx with react context?

**It is not mandatory to use react context with Mobx but it is recommended now officially on the mobx-react website.**

Earlier, Mobx had an `Provider/inject` pattern. There’s one `Provider` in the root, `inject` is used to inject the mobx store to any component and `observer` is used to make a component re-render whenever the store is modified.

This `Provider/inject` works great but it is heavily opinionated. **`Provider/inject` pattern still works with mobx-react 6.x but it is considered as obsolete now**. You can read more about it here – [Why inject pattern is obsolete](https://mobx-react.js.org/recipes-inject)

So, It is better to use Mobx with react context starting from mobx-react 6.x but the problem is the [official docs](https://mobx-react.js.org/recipes-context) on setting up Mobx with react context is quite confusing.

If you read the docs then there will be many questions in your mind. Like **how to use Mobx react context with class components** , how to use Mobx react context with functional components, how to observe for changes on class components and functional components.

Official docs only mention how to use context and mobx with hooks but there’s nothing related to class components. I’m pretty sure that majority of the react developers are still using class components even if they have started using hooks.

So I’m writing this detailed guide on how to setup Mobx with react context to clarify any such questions.

## How to setup Mobx with [react native](https://dev.to/codingislove/building-youtube-ui-in-30-mins--react-native-tutorial-38mo-temp-slug-565632)

This exact setup works with react native as well. Just skip the react specific sections. I’m assuming that you have a basic react native app generated using react-native-cli. Everything else remains the same.

## Basic react app

I’m starting from scratch just to be clear but if you already have a react app setup then that is completely fine and you can skip this section.

Create a basic react app using `create-react-app` by running the following command :

```
npx create-react-app my-app
```

You have a basic app now. You can `cd` into the newly created app and run it using.

```
cd my-app && yarn start
```

If you go to `http://localhost:3000/` then you can see a basic react app running which looks like this :

![setup mobx with react context](https://codingislove.com/wp-content/uploads/2020/06/mox-react-context-app-1024x500.png)

We need to eject from create-react-app for enabling Mobx decorators syntax. Eject using :

```
yarn eject
```

## Install Mobx and Mobx-react

Mobx is the main library and mobx-react has the mobx binding for react. Install both Mobx and Mobx-react using the following command :

```
yarn add mobx mobx-react
```

If you had already setup react app and Mobx then **Make sure that mobx-react is 6.x or higher**

## Enable Mobx decorators syntax

You can use Mobx without the decorators syntax as well but using decorators simplifies the code so let’s enable it.

## Enable decorators for react app

Make sure that you have ejected from create-react-app as mentioned above using `yarn eject`

Install the babel plugins for decorators using :

```
yarn add --dev @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties
```

Go to package.json file and replace the babel section with the following

```
"babel": {
    "presets": [
      "react-app"
    ],
    "plugins": [
      ["@babel/plugin-proposal-decorators", { "legacy": true }],
      ["@babel/plugin-proposal-class-properties", { "loose": true }]
    ]
  }
```

## Enable decorators for react-native

Install the babel plugins for decorators using :

```
yarn add --dev @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties
```

Go to `babel.config.js` and paste this :

```
module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    ['@babel/plugin-proposal-decorators', { legacy: true }],
    ['@babel/plugin-proposal-class-properties', { loose: true }],
  ],
};
```

Decorator syntax is enabled now!

## Setup a basic Mobx store

go to src folder in react app, create a folder named `services` and create a file named `store.js` inside the services folder. You create this file anywhere in the project as per your preference. I’m just showing an example to organize it properly.

Go to newly created `store.js` file and paste the following code

```
import React from "react";
import { action, observable } from "mobx";

/* Store start */
export default class Store {
  @observable title = "Coding is Love";

  @observable user = {
    userId: 1,
    name: "Ranjith kumar V",
    website: "https://codingislove.com",
    email: "ranjith@codingislove.com",
  };

  @action
  setUser(user) {
    this.user = user;
  }

  @action
  updateUser(data) {
    this.user = { ...this.user, ...data };
  }

  @action
  clearUser() {
    this.user = undefined;
  }

  @action
  setTitle(title) {
    this.title = title;
  }
}
/* Store end */

/* Store helpers */
const StoreContext = React.createContext();

export const StoreProvider = ({ children, store }) => {
  return (
    <StoreContext.Provider value={store}>{children}</StoreContext.Provider>
  );
};

/* Hook to use store in any functional component */
export const useStore = () => React.useContext(StoreContext);

/* HOC to inject store to any functional or class component */
export const withStore = (Component) => (props) => {
  return <Component {...props} store={useStore()} />;
};
```

## Store explanation

Its a very simple store with a user object to store user data, a title string, a few functions to modify the user and title. **`@observable` is used to tell mobx to re-render components whenever an observable property is modified.**

`@action` is a function that is used for modifying observables. Running an `@actions` also triggers `autoRun` functions if you have set up any of them.

useStore is our custom hook to use mobx store in any functional component

withStore is a custom HOC (Higer order component) to use mobx store in any class component.

## Mobx Provider setup

Go to your main file. `App.js` in case of create-react-app and paste this :

```
import React from "react";
import Home from "./screens/Home";
import Store, { StoreProvider } from "./services/store";

const store = new Store();
/* Create a new store */

function App() {
  return (
    <StoreProvider store={store}>
      <Home />
    </StoreProvider>
  );
}

export default App;
```

We are using `StoreProvider` in the root and a single component named Home

Create a folder called `screens` and create a file named `Home.js` inside the folder and paste this :

```
import React, { Component } from "react";
import logo from "../logo.svg";
import "../App.css";
import { observer } from "mobx-react";
import { withStore } from "../services/store";

@withStore
@observer
class Home extends Component {
  toggleTitle = () => {
    const { store } = this.props;
    if (store.title === "Coding is Love") {
      store.setTitle("Mobx React Context");
    } else {
      store.setTitle("Coding is Love");
    }
  };

  render() {
    const { store } = this.props;
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <a
            className="App-link"
            href="https://codingislove.com"
            target="_blank"
            rel="noopener noreferrer"
          >
            {store.title}
          </a>
          <button onClick={this.toggleTitle} style={{ margin: 20 }}>
            Toggle title
          </button>
        </header>
      </div>
    );
  }
}

export default Home;
```

We are using @withStore HOC that was created in `store.js` to use our store. @observer is used to re-render the component whenever store is modified.

This is an example of **How to use Mobx and react context setup with class components**

**withStore HOC injects store into the component as a prop** so we can accessing it using `this.props.store`

I’ve written one small function named `toggleTitle` just to show how to modify the store.

**That’s it! We’ve completed the mobx setup!** Now, Whenever we modify the store, all the components with observer get re-rendered automatically.

If you want to know how to use the `useStore` hook then continue reading.

## useStore hook for functional components

This is an example on How to use **Mobx and react context with functional components**. Create a folder named `components` inside src folder. Create a file named `Username.js` inside `components` folder.

Go to `Username.js` and paste this :

```
import React from "react";
import { observer } from "mobx-react";
import { useStore } from "../services/store";

const Username = observer(() => {
  const store = useStore();
  return <div style={{ fontSize: 14 }}>- By {store.user.name}</div>;
});

export default Username;
```

All we have to do is use observer so that the component re-renders when store is modified. Use the store using `useStore` hook. It is as simple as that.

Now import the `Username` in `Home.js` and use it.

Final code looks like this:

```
import React, { Component } from "react";
import logo from "../logo.svg";
import "../App.css";
import Username from "../components/Username";
import { observer } from "mobx-react";
import { withStore } from "../services/store";

@withStore
@observer
class Home extends Component {
  toggleTitle = () => {
    const { store } = this.props;
    if (store.title === "Coding is Love") {
      store.setTitle("Mobx React Context");
    } else {
      store.setTitle("Coding is Love");
    }
  };

  render() {
    const { store } = this.props;
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <a
            className="App-link"
            href="https://codingislove.com"
            target="_blank"
            rel="noopener noreferrer"
          >
            {store.title}
          </a>
          <button onClick={this.toggleTitle} style={{ margin: 20 }}>
            Toggle title
          </button>
          <Username />
        </header>
      </div>
    );
  }
}

export default Home;
```

## Wrapping up

Final output looks like this :

![Mobx react context example](https://codingislove.com/wp-content/uploads/2020/06/mox-react-context-demo-1024x500.png)

Full source code for this boilerplate project is available here – [https://github.com/codingislove01/mobx-react-context](https://github.com/codingislove01/mobx-react-context)

If you have any questions or feedback then let me know in the comments below ![✌](https://s.w.org/images/core/emoji/12.0.0-1/72x72/270c.png)

The post [How to setup Mobx with react context](https://codingislove.com/setup-mobx-react-context/) appeared first on [Coding is Love](https://codingislove.com).