What it is
MobX is a simple, scalable, and battle-tested state management library for JavaScript applications. It allows you to manage application state outside of components while keeping your UI automatically in sync with state changes.
MobX uses observables to hold state, actions to modify state, and reactions or observers to automatically update the UI. Computed values allow derived state to be calculated efficiently. MobX integrates seamlessly with React via the `observer` higher-order component or hooks.
Installation
npm install mobx mobx-reactGetting started
The smallest useful thing you can do with it, and what each part means.
import { makeAutoObservable } from 'mobx';
class CounterStore {
count = 0;
constructor() {
makeAutoObservable(this);
}
increment() {
this.count += 1;
}
decrement() {
this.count -= 1;
}
}
const counterStore = new CounterStore();
export default counterStore;import { observer } from 'mobx-react';
import counterStore from './CounterStore';
const Counter = observer(() => (
<div>
<button onClick={() => counterStore.decrement()}>-</button>
<span>{counterStore.count}</span>
<button onClick={() => counterStore.increment()}>+</button>
</div>
));Advanced usage
Where the library earns its place over a simpler alternative.
import { makeAutoObservable } from 'mobx';
class CartStore {
items = [];
constructor() { makeAutoObservable(this); }
addItem(item) { this.items.push(item); }
get total() { return this.items.reduce((sum, item) => sum + item.price, 0); }
}
const cartStore = new CartStore();import { reaction } from 'mobx';
reaction(() => cartStore.total, total => {
console.log('Cart total changed to:', total);
});import { makeAutoObservable, runInAction } from 'mobx';
class AsyncStore {
data = [];
loading = false;
constructor() { makeAutoObservable(this); }
async fetchData() {
this.loading = true;
const response = await fetch('/api/data');
const result = await response.json();
runInAction(() => {
this.data = result;
this.loading = false;
});
}
}Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- UI not updating
- Ensure components using observables are wrapped with `observer` or use `useObserver` hook.
- State mutation outside action
- Enable `enforceActions` and make all state modifications inside actions.
- Computed values not recalculating
- Make sure computed properties access observable state and are not dependent on non-observable values.
Best practices
- Use small, focused stores to manage state for different parts of the app.
- Wrap React components with `observer` to automatically update UI when observables change.
- Use `computed` for derived state to optimize performance.
- Avoid directly mutating observables outside of actions for predictable behavior.
- Leverage MobX DevTools for debugging and inspecting state changes.
Background
Why it exists, and what it was reacting to.
MobX was created by Michel Weststrate to provide a reactive state management solution that is less verbose and more intuitive than Redux. It leverages observables and derivations to automatically update UI components when state changes, reducing boilerplate and promoting a reactive programming paradigm.
