DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • An Introduction to Object Mutation in JavaScript
  • Metaprogramming With Proxies and Reflect in JavaScript
  • A Comprehensive Guide To Working With JSON in JavaScript
  • JavaScript's Secret Weapon: Unraveling the Mysteries of Proxies

Trending

  • Artificial Intelligence, Real Consequences: Balancing Good vs Evil AI [Infographic]
  • Comparing SaaS vs. PaaS for Kafka and Flink Data Streaming
  • Doris: Unifying SQL Dialects for a Seamless Data Query Ecosystem
  • How the Go Runtime Preempts Goroutines for Efficient Concurrency
  1. DZone
  2. Coding
  3. Languages
  4. The Drawbacks of MobX

The Drawbacks of MobX

The pros and cons of MobX

By 
Alexey Shepelev user avatar
Alexey Shepelev
DZone Core CORE ·
Sep. 20, 21 · Opinion
Likes (8)
Comment
Save
Tweet
Share
8.5K Views

Join the DZone community and get the full member experience.

Join For Free

I would like to talk about what I could rarely find in articles covering MobX, about those drawbacks that ruin the impression of use, as well as how to crack this problem. I also need to describe its pros to justify my own choice. So, let’s start.

MobX is a state manager, which now has a new version 6 that works due to Proxy. The further opinion is based on using MobX v6 together with the React library when developing mobile (React Native) and web applications. It is worth clarifying that I used MobX v4, react-easy-state, Redux, Zustand in previous projects, and I’m also familiar with a dozen alternative state managers at the level of reading their documentation. I would also like to note that all the pros and cons listed below aren’t complete and can be detected if compared to other state managers.

Pros

With the release of version 6, classes and decorators are no longer needed. I see both of them as unnecessary and even harmful syntactic sugar. So, I believe the ability to create object repositories in the new version is an excellent choice.
Example:

JavaScript
 
import { makeAutoObservable } from 'mobx';
export const blogStore = makeAutoObservable({
  blogs: {},
  posts: {},
  createBlog: () => {},
  createPost: () => {},
});


It is quite natural to use repositories as objects. From here follow type hints, references to fields, auto-import, and other goodies – Proxy works wonders.
Example:

JavaScript
 
import { blogStore } from 'stores';
const Blog = () => {
  const posts = chatStore.posts;
  const onPress = chatStore.createPost;
  return null;
};


You can easily change states. Yes, I’m all for immutability, but this is where I don’t see any reason for this. The fact is that, if needed, I can create full snapshots of all repositories by putting them in a single object and calling JSON.stringify or something custom. In Redux, the problem is solved by including "immer" for deeply nested objects. And yes, it all depends on how precise the object change is, and we must use functional programming tools wherever it is possible.
Example:

JavaScript
 
import { makeAutoObservable } from 'mobx';
export const blogStore = makeAutoObservable({  
  posts: {},
  createPost: (post) => {
    blogStore.posts[post.id] = post;
  },
});


Selectors. This is where MobX looks amazing. When we need data slices only based on repositories, we use getters. In other cases, we store parameterized selectors in separate files using computedFn from MobX-utils. At the same time, they all are automatically memoized by MobX, which allows for good application performance. Not that Redux has any problems with reselect, but here it is easier to write and read code.
Example:

JavaScript
 
import { makeAutoObservable } from 'mobx';
import { accountStore } from 'stores/accountStore';
export const blogStore = makeAutoObservable({
  posts: {},
  get myPosts() {
    return Object.values(posts).filter((post) => post.userId === accountStore.userId);  
  }
});

Cons

Wrapping components with observer HOC to make them more reactive. Just like any state managers that aren’t based on hooks or selectors, this requires writing snippets for components and takes some getting used to. Besides, this involves memoizing components. But since all of our components are already memoized, we’re just replacing one call with another.
Example:

JavaScript
 
import { observer } from 'mobx-react-lite';
const Blog = () => null;
export default observer(Blog);


Components fail when their code, containing hooks, is updated on the fly. More specifically, adding or removing a hook with subsequent saving leads to failure. It’s about the poor performance of Fast Refresh with a HOC wrapped around the exported default component, rather than MobX. So as not to change the usual project structure in which we use export default observer (Component) to export components by default, I had to study writing Babel plugins. I created a plugin that wrapped the observer call into the component function declaration and removed the call from the export. That was fine. Of course, you might ask why I would do that. After all, according to the MobX documentation, the component needs to be wrapped just when it is declared. My answer would be that when using HOCs in the export, the code looks more beautiful and has less nesting. Besides, changing memo to observer is easier when you need to use MobX stores.
Example:

JavaScript
 
import { observer } from 'mobx-react-lite';
const Blog = () => {
 // removing or adding a hook will cause fast refresh to fail
 const [visible, setVisible] = useState(false);
 return null;
};
export default observer(Blog);


You need to be careful when working with MobX objects inside a component. Since we’re working with reactive mutable data, it is no longer possible to hope for their immutability when transferred to somewhere else, including inside other objects, unlike when using Redux data. For example, if we want to keep the same change history in some editor. In this case, use a MobX function called toJS, which converts data into regular JavaScript objects.
Example:

JavaScript
 
import { blogStore } from 'stores';
import { useRef } from 'react';
import { toJS } from 'mobx';
const Blog = () => {
  const posts = blogStore.posts;
  const prevMessages = useRef();
  const onPress = () => {
    const postsPurified = toJS(posts);
    prevPosts.current = postsPurified;
    // not to call toJS before that = shoot yourself in the foot
  };
  return null;
};


There is a lack of good tools similar to Redux DevTools. Luckily, I had some developments for react-easy-state, which allowed me to supplement them and create a library so that MobX could work with Redux DevTools. In short, I use it to wrap all MobX actions and replace them with logging functions, as well as create snapshots of repositories when they are called. Monitoring changes to MobX stores is now easy and enjoyable.

And of course, I cannot but mention how inconvenient it is to debug Proxy objects, which are the main part of MobX 6. You always have to open them to click on the target field, where the object we need is located. When displaying logs, you can use wrapping in toJS from MobX, but I still don’t have any solution for debugging. Perhaps there is a setting for displaying Proxy in the browser and Visual Studio Code, I don’t know yet.

Conclusion

MobX is a worthy state manager, although it required some work to meet the needs of our project. Despite some problems when debugging Proxy objects, it helps write code easily and provides excellent code readability. In my opinion, its good performance due to memoized getters and computedFn from MobX-utils makes it one of the best solutions.

Object (computer science) JavaScript

Opinions expressed by DZone contributors are their own.

Related

  • An Introduction to Object Mutation in JavaScript
  • Metaprogramming With Proxies and Reflect in JavaScript
  • A Comprehensive Guide To Working With JSON in JavaScript
  • JavaScript's Secret Weapon: Unraveling the Mysteries of Proxies

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!