MobX is a signal-based, battle-tested state management library that makes state management simple and scalable by transparently applying functional reactive programming (FRP). It automatically tracks state changes through the observer pattern, and when observable state changes, MobX automatically updates all derived values and reactions that depend on that state.
Core Concepts
1. Observable
Use observable or makeObservable to convert ordinary JavaScript objects, arrays, Maps, etc., into observable objects. Changes to observable state are automatically tracked by MobX.
javascriptimport { observable } from 'mobx'; class TodoStore { @observable todos = []; @observable filter = 'all'; }
2. Action
Actions are the only way to modify state. Use the action decorator or runInAction function to wrap state modification logic. This ensures state changes are traceable and predictable.
javascriptimport { action } from 'mobx'; class TodoStore { @action addTodo(text) { this.todos.push({ text, completed: false }); } }
3. Computed
Computed values are derived values that automatically update based on observable state, similar to Vue's computed properties. They only recalculate when their dependent observable state changes.
javascriptimport { computed } from 'mobx'; class TodoStore { @computed get activeTodos() { return this.todos.filter(todo => !todo.completed); } }
4. Reaction
Reactions are side effects that automatically execute when observable state changes, similar to React's useEffect. Common reaction types include autorun, reaction, and when.
javascriptimport { autorun } from 'mobx'; autorun(() => { console.log('Current todo count:', this.todos.length); });
How It Works
MobX workflow:
- Tracking phase: When a reaction or computed value reads observable state, MobX establishes dependency relationships
- Change phase: Modify observable state through actions
- Notification phase: MobX automatically notifies all reactions and computed values that depend on that state
- Update phase: Reactions and computed values automatically re-execute or recalculate
Differences from Redux
| Feature | MobX | Redux |
|---|---|---|
| State management | Automatic tracking, no manual subscription | Requires manual subscription and dispatch |
| Code volume | Less, more concise | More, requires defining actions, reducers |
| Learning curve | Gentler | Steeper |
| State structure | Can be nested | Recommend flattening |
| Debugging tools | MobX DevTools | Redux DevTools |
Best Practices
- Always use actions to modify state: Ensure state changes are traceable
- Use computed values appropriately: Avoid repeated calculations and improve performance
- Avoid overusing observable: Only use it for state that needs tracking
- Use makeAutoObservable: Simplify decorator configuration
- Separate business logic from UI: Concentrate state management logic in stores
Use Cases
MobX is suitable for:
- Medium to large React applications
- Projects requiring complex state management
- Teams that want rapid development
- Scenarios with complex and nested state structures
Not suitable for:
- Very simple applications
- Scenarios requiring strict time-travel debugging
- Teams preferring functional programming paradigms