Unlock the Power of MobX: A Revolutionary State Management Tool
Understanding MobX Core Concepts
When building web applications, managing state effectively is crucial for a seamless user experience. MobX, a simple, scalable, and standalone state management library, takes it a step further by preventing inconsistent state and ensuring automatic derivations.
MobX introduces three essential concepts: state, actions, and derivations. The application state encompasses the entire model of an application, comprising various data types. Actions are methods that manipulate and update the state, while derivations are values derived from the application state without further interaction.
There are two types of derivations: reactions and computed values. Reactions trigger automatic side effects when the state changes, whereas computed values return a distinct value derived from the current state.
Demonstrating MobX with a Pet Owner Store
To illustrate how MobX works, let’s create a pet owner store example. We’ll start by creating a basic representation of the store using a class that includes pets and owners as instance properties.
class PetOwnerStore {
pets = [];
owners = [];
constructor() {
// Initialize store
}
}
We’ll then introduce methods to create new pets and owners, update existing ones, and remove them from the store. Finally, we’ll grant access to get total pets, total owners, and pets by owner.
class PetOwnerStore {
//...
createPet(pet) {
// Create new pet
}
createOwner(owner) {
// Create new owner
}
updatePet(pet) {
// Update existing pet
}
updateOwner(owner) {
// Update existing owner
}
deletePet(pet) {
// Remove pet from store
}
deleteOwner(owner) {
// Remove owner from store
}
getTotalPets() {
// Return total pets
}
getTotalOwners() {
// Return total owners
}
getPetsByOwner(owner) {
// Return pets by owner
}
}
Making the MobX Store Reactive
To make our store reactive, we’ll use the makeObservable
function provided by MobX. This function turns a class into an observable state, which refreshes and updates itself whenever parts of its fields change.
import { makeObservable } from 'obx';
class PetOwnerStore {
//...
constructor() {
makeObservable(this, {
pets: observable,
owners: observable,
createPet: action,
createOwner: action,
updatePet: action,
updateOwner: action,
deletePet: action,
deleteOwner: action,
getTotalPets: computed,
getTotalOwners: computed,
getPetsByOwner: computed,
});
}
}
Integrating MobX with React
Now, let’s add a frontend to our store using React. We’ll create a new React app and copy our PetOwner
MobX store to the src
folder.
We’ll then create a PetList
component to display the store’s details and modify it to add a new pet to the list.
import React from 'eact';
import { observer } from 'obx-react-lite';
import { PetOwnerStore } from './PetOwnerStore';
const PetList = observer(() => {
const petOwnerStore = new PetOwnerStore();
const handleAddPet = () => {
petOwnerStore.createPet({ name: 'New Pet' });
};
return (
Pets:
-
{petOwnerStore.pets.map((pet) => (
- {pet.name}
))}
);
});
Managing Frontend State with MobX and React
We’ll continue to explore how to list, update, and delete items in the store using MobX and React.
We’ll create a table to list the items in the pets
state and buttons to update and delete pet items from the store.
import React from 'eact';
import { observer } from 'obx-react-lite';
import { PetOwnerStore } from './PetOwnerStore';
const PetList = observer(() => {
const petOwnerStore = new PetOwnerStore();
const handleUpdatePet = (pet) => {
petOwnerStore.updatePet(pet);
};
const handleDeletePet = (pet) => {
petOwnerStore.deletePet(pet);
};
return (
Pets:
{petOwnerStore.pets.map((pet) => (
))}
Name | Actions |
---|---|
{pet.name} |
|
);
});
Finalizing the Application
To complete our application, we’ll create a new component, OwnerList
, and update it with the necessary code.
import React from 'eact';
import { observer } from 'obx-react-lite';
import { PetOwnerStore } from './PetOwnerStore';
const OwnerList = observer(() => {
const petOwnerStore = new PetOwnerStore();
return (
Owners:
-
{petOwnerStore.owners.map((owner) => (
- {owner.name}
))}
);
});
We’ll then import the component inside App.jsx
, passing it to the store as we did for the PetList
component.
Using MobX to Manage Remote Data
Finally, we’ll modify PetOwnerStore
to load data from a remote server. We’ll add a prefetchData
method to simulate a network request and call the create methods on the class to add the newly available data into the store.
class PetOwnerStore {
//...
prefetchData() {
// Simulate network request
const data = [
{ id: 1, name: 'Pet 1' },
{ id: 2, name: 'Pet 2' },
{ id: 3, name: 'Pet 3' },
];
data.forEach((pet) => {
this.createPet(pet);
});
}
}