What is MobX? & How to create an app with MobX & React?

What is MobX? & How to create an app with MobX & React?

MobX is a simple and scalable state management library used in the Lit and React communities. MobX stands apart from other management libraries, such as Redux, because it requires practically no boilerplate and utilizes ordinary TypeScript syntax to refresh or update the state. It makes it simple to learn and use. Hence creating an enterprise solution app with MobX is also an easy way. At the center of MobX is the observation state, which gets refreshed through activities set off by occasion. When the state changes, figured values are restored, and any secondary effects are run.

MobX stores computed values and possibly assesses them, assuming they get utilized and if any observables have changed since the last added. MobX suggests using two stores: one for the domain object and one for the application state. It's ideal for keeping the business and application state separate for simpler testing and reuse. These two stores get overseen by a central store called the AppStore.

Let's discuss MobX in detail and how we create a successful first application.

Core Concept Of MobXs

There are mainly three core concepts in MobXs:

  • Observables

It characterizes a notable field that stores the state. Observables in MobX permit us to add recognizable abilities to our information structures like classes, items, and arrays and make our property observables.

  • Actions

It is a function that changes the observable data. It denotes a strategy as an action that will update the state.

  • Reactions

It denotes a getter that will get new realities from the state and cache its result.

Pros of using MobX :

  1. It provides many built-in abstractions that lead to less coding.

  2. It is mainly used to develop any app faster and in less time.

  3. With the help of an observable attribute, updates can be done automatically.

Cons of using MobX :

  1. The debugging is difficult, as the tools available for Mobx are not much better and result in unpredictable responses.

  2. It is less maintainable.

  3. It has a less online community and developer support.

How to create your first app with MobX & React:

We will create a simple application where users can react to images and comment on them, similar to Facebook.

Before creating an application with MobX, You must also know about React in detail.

Let's start with creating a project setup!

  • Firstly, we will install NPM and Node.js on your system.

  • Now use custom webpack configuration. And set up the project to enable decorators.

  • For the initial setup, pull the master branch from this repository.

  • Run yarn to install dependencies. Now start the project using yarn start.

  • Enable ESNext decorators.

  • Now add the below configuration to the .babelrc file as shown

"plugins": [
        [
            "@babel/plugin-proposal-decorators",
            {
                "legacy": true
            }
        ],
        [
            "@babel/plugin-proposal-class-properties",
            {
                "loose": true
            }
        ]
    ]
  • For design style, pull the design branch for styles under the CSS folder inside the src directory.

  • Connect the state layer to the React view layer; install the mobx state management solution & `mobx-react library`.

  • yarn add mobx mobx-react; hence, we will start adding features using Mobx.

  • Let's start creating a Store.jsx under the store folder.

import { observable, action } from 'mobx'

class Store {
    @observable likesCount = 12

    @action updateCount{
        this.likesCount++;
    }
}

const storeInstance = new Store()
export default storeInstance;
  • Make the store accessible in the app by using the Context API in main.js

  • Access the store and class properties in Count.jsx using useContext.

  • To increase likesCount when the user clicks on the Like button, we will use the updateCount action from the store we've already defined. Handle onClick action in Buttons.jsx.

  • Wrap the component in the observer function or implement the useObserver hook, like below. So let's update Count.jsx as:

import { useObserver } from 'mobx-react';

...
  return useObserver(() => (
        <div className=" row reactions-count">
            <div className="col-sm" align="left">
                <i className="fa fa-thumbs-up" />{store.likesCount}
            ...
            ...
        </div>
        </div>
    ))
  • Let's start working on the comments section. Let's create a visual comments field. Add the following in store.jsx.

Now, access the comments property of the store class from Comments.jsx using useContext.

The Comments component will now render the comments from the store as shown below:

import React, { useContext } from 'react';
import { StoreContext } from '../main';

export default function Comments() {
    const store = useContext(StoreContext)
    return (
        <table className="table">
            <tbody>
                {
                    store.comments.map((comment, index) => {
                        return (
                            <tr key={index}>
                                <td>
                                    {comment}
                                </td>
                            </tr>
                        )

                    })
                }
            </tbody>
        </table>
    )
}
  • Let's create an action called postComment in the store that pushes the new comment into the previous array of comments. Add the following lines of code in store.jsx.

Then update the Form.jsx component as:

import React, { useContext } from 'react';
import { StoreContext } from '../main';

Export default class Form extends React.Component {

    handleSubmit = (e, store) => {
        e.preventDefault();
        store.postComment(this.comment.value);
        this.comment.value = "";
    }

    render() {
        return (
            <StoreContext.Consumer>
                {
                    store => (

                        <form onSubmit={(e) => this.handleSubmit(e, store)}>
                            <div>
                                <input type="text" id={'comment'} className="form-control" placeholder={"Write a comment ..."} ref={node => {
                                    this.comment = node;
                                }} />
                            </div>
                        </form>
                    )
                }
            </StoreContext.Consumer>
        )
    }
}
  • Created a function that calls the store's postComment action when the user submits the comment and sets the input field to empty after submission.

  • Then add focus method on onClick handler of comment button in Buttons.jsx component.

  • To get the CommentsCount, we will create a CommentsCount getter function that computes the observable comments array's length. MobX will ensure commentsCount updates automatically whenever the comments array changes. In store.jsx add the following:

@computed get commentsCount(){
       return this.comments.length;
   }

Then update the following lines in Count.jsx.

<div className="col-sm" align="right">
 {store.commentsCount} comments
</div>
  • Now it's time to make an API call and asynchronous codes that are frequent in applications. Since this is a custom webpack configuration to enable async/await, update the .babelrc file with the following.
"presets": [
        ["@babel/preset-env",
        {
            "targets": {
              "node": "10"
            }
          }
        ],
        "@babel/preset-react"
    ],
  • Let's create an image store with observable imageUrl containing the default value. Then we create a fetchimage action that returns the JSON response of a single character.

  • After await, a new asynchronous function gets started, so after each await, state modifying code should be wrapped as action.

  • One way is to use the runInAction, a simple utility that takes a code block and executes an anonymous action. Here we are wrapping the state modifying part after await in runInAction.

import { action, runInAction, observable } from "mobx";

class ImageStore {

    id = 1

    @observable imageUrl = `https://rickandmortyapi.com/api/character/avatar/1.jpeg`

    @action async fetchImage() {
            const characterId = ++this.id
            const response = await fetch(`https://rickandmortyapi.com/api/character/${characterId}`)
            const data = await response.json()
            runInAction(() => {
                this.imageUrl = data.image
            })
    }
}
const imageStore = new ImageStore()
export default imageStore;

Note: You can also run only the state-modifying part of the callback.

  • Then in Card.jsx component.

  • Import the imageStore and set the image source to the observable imageUrl from the store.

  • Implement useObserver to react to changes.

  • Add a button with an onClick handler that calls the fetchImage to get the image URL.

import React from "react";
import Count from "./Count";
import Buttons from "./Buttons";
import imageStore from '../store/ImageStore'
import { useObserver } from "mobx-react";

export default function Card() {
    return (
        useObserver(() => (
            <div className="card">
                <img src={imageStore.imageUrl} className="card-img-top" alt="..." />
                <button className="btn btn-light" onClick={() => { imageStore.fetchImage() }}>
                    <i className="fa fa-chevron-right" />
                </button>
                <Count />
                <div className="card-body" >
                    <Buttons />
                </div>
            </div>
        ))
    );
}

We're done here! You will get your output through the above process..

Mobx docs are well-written and contain a lot of best practices. As per our QL experts, only a library is ideal for some works in this current software development era, which is also true for MobX. Such as documentation, dev tools are not rich like Redux, but so far, it is solving our problems of an enterprise app.

Many organizations need to learn about MobX because they mainly use Redux because of its popularity in React. But as per our expert, MobX can also be a great state management solution for many React developers interested in creating business solutions.

Any queries, suggestions, or comments? Drop them in the comment section.

Thanks!!!

Explore- 4 React Native App Projects You Should Practice As A Beginner

Did you find this article valuable?

Support Quokka Labs' Blogs by becoming a sponsor. Any amount is appreciated!