State management is a crucial aspect of modern web applications, especially as they become more complex. React, a popular library for building user interfaces, provides a basic state management system through useState and useReducer hooks. However, as applications grow, managing state with these hooks alone can become cumbersome. This is where state management libraries like MobX come into play.
MobX is a battle-tested library that makes state management simple and scalable by using reactive programming principles. It allows you to manage the state of your application with minimal boilerplate code and offers a clear and straightforward mental model for how state changes over time
Before diving into advanced concepts, let’s set up MobX in a React project. Ensure you have Node.js installed, then follow these steps:
npx create-react-app mobx-demo
cd mobx-demo
npm install mobx mobx-react-lite
Observables are the core of MobX’s reactivity system. They represent the state of your application. When an observable changes, any part of the code that depends on it will automatically update.
import { observable } from "mobx";
class TodoStore {
@observable todos = [];
}
const todoStore = new TodoStore();
In this example, todos
is an observable array. Any changes to this array will be tracked by MobX.
Actions are functions that modify the state. They help in organizing and managing how state changes occur, ensuring that all state modifications are tracked and can trigger updates.
import { action } from "mobx";
class TodoStore {
@observable todos = [];
@action addTodo = (todo) => {
this.todos.push(todo);
}
}
const todoStore = new TodoStore();
Here, addTodo
is an action that modifies the todos
observable.
Observers are React components that react to changes in observables. When an observable that an observer depends on changes, the observer will re-render.
import React from "react";
import { observer } from "mobx-react-lite";
const TodoList = observer(({ store }) => (
{store.todos.map((todo, index) => (
- {todo}
))}
));
In this example, TodoList
is an observer component that re-renders whenever store.todos
changes.
Computed values are values derived from observables that will automatically update when the underlying observables change. They are similar to derived state in React.
import { computed } from "mobx";
class TodoStore {
@observable todos = [];
@computed get completedTodos() {
return this.todos.filter(todo => todo.completed);
}
}
const todoStore = new TodoStore();
Here, completedTodos
is a computed value that derives from todos
.
Reactions are a lower-level API that can be used to perform side effects in response to state changes. They are more flexible than observers but require more manual management.
import { reaction } from "mobx";
reaction(
() => todoStore.todos.length,
length => {
console.log(`Number of todos: ${length}`);
}
);
In this example, the reaction runs whenever the length of todos
changes.
For larger applications, MobX State Tree (MST) provides a more structured and opinionated way to manage state. MST introduces concepts like models, snapshots, and middleware.
npm install mobx-state-tree
import { types } from "mobx-state-tree";
const Todo = types
.model("Todo", {
id: types.identifier,
title: types.string,
completed: false
})
.actions(self => ({
toggle() {
self.completed = !self.completed;
}
}));
const RootStore = types.model("RootStore", {
todos: types.array(Todo)
});
const store = RootStore.create({
todos: []
});
import React from "react";
import { observer } from "mobx-react-lite";
import { onSnapshot } from "mobx-state-tree";
import { store } from "./path-to-store";
const TodoList = observer(() => (
{store.todos.map(todo => (
-
{todo.title}
))}
));
onSnapshot(store, snapshot => {
console.log("Snapshot: ", snapshot);
});
export default TodoList;
MobX provides a powerful and flexible way to manage state in React applications. By using observables, actions, computed values, and reactions, you can create responsive and maintainable state management solutions. For larger applications, MobX State Tree offers additional structure and capabilities. Happy coding !❤️