Pourquoi MobX avec React : guide complet ?
MobX est une bibliothèque JavaScript populaire pour la gestion de l'état dans les applications React. Elle offre un modèle de programmation réactive qui permet aux composants React d'être mis à jour automatiquement en fonction des changements dans le state. Ce guide approfondi explique comment utiliser MobX avec React en abordant les concepts fondamentaux, la mise en pratique via un projet fil rouge et les erreurs courantes lors de l'utilisation.
Prerequis
- Connaissance avancée de JavaScript et ES6+
- Expérience avec React
- Familiarité avec le concept de state management dans React
- Node.js et npm installés (versions récentes recommandées)
Concepts fondamentaux
Store
Un store est un conteneur pour les données statiques, qui sont liées au modèle métier de l'application. Les stores gèrent la logique métier et émettent des actions lorsqu'un changement se produit.
// store.js
import { observable, action } from 'mobx';
class TodoStore {
@observable todos = [];
@action addTodo(todo) {
this.todos.push(todo);
}
@action removeTodo(index) {
this.todos.splice(index, 1);
}
}
export default new TodoStore();
Observables
Les observables sont des propriétés qui sont liées au store. Lorsqu'une observable change, tous les composants React qui la consomment sont automatiquement mis à jour.
// App.js
import React from 'react';
import { observer } from 'mobx-react';
import TodoStore from './store';
const TodoList = observer(() => {
return (
<ul>
{TodoStore.todos.map((todo, index) => (
<li key={index}>
{todo}
<button onClick={() => TodoStore.removeTodo(index)}>Remove</button>
</li>
))}
</ul>
);
});
const App = () => {
return (
<div>
<input
type="text"
onKeyPress={(e) => {
if (e.key === 'Enter') {
TodoStore.addTodo(e.target.value);
e.target.value = '';
}
}}
/>
<TodoList />
</div>
);
};
export default App;
Actions
Les actions sont des fonctions qui modifient les observables. Elles peuvent être appelées pour mettre à jour l'état du store.
// store.js (suite)
@action addTodo(todo) {
this.todos.push(todo);
}
@action removeTodo(index) {
this.todos.splice(index, 1);
}
Computed Values
Les computed values sont des valeurs qui dépendent d'autres observables. Elles sont recalculées automatiquement lorsque les observables dont elles dépendent changent.
// store.js (suite)
@computed get todoCount() {
return this.todos.length;
}
Mise en pratique : projet fil rouge
Étape 1 : Création du projet
Commencez par créer un nouveau projet React et installer MobX et MobX-React.
npx create-react-app mobx-todo-list
cd mobx-todo-list
npm install mobx mobx-react
Étape 2 : Configuration de MobX
Créez un fichier store.js pour définir le store.
// store.js
import { observable, action, computed } from 'mobx';
class TodoStore {
@observable todos = [];
@action addTodo(todo) {
this.todos.push(todo);
}
@action removeTodo(index) {
this.todos.splice(index, 1);
}
@computed get todoCount() {
return this.todos.length;
}
}
export default new TodoStore();
Étape 3 : Création du composant
Créez un fichier TodoList.js pour afficher la liste des todos.
// TodoList.js
import React from 'react';
import { observer } from 'mobx-react';
import TodoStore from './store';
const TodoItem = ({ todo, index }) => {
return (
<li key={index}>
{todo}
<button onClick={() => TodoStore.removeTodo(index)}>Remove</button>
</li>
);
};
const TodoList = observer(() => {
return (
<ul>
{TodoStore.todos.map((todo, index) => (
<TodoItem todo={todo} index={index} key={index} />
))}
</ul>
);
});
export default TodoList;
Étape 4 : Création du composant d'ajout de todos
Créez un fichier AddTodo.js pour ajouter de nouveaux todos.
// AddTodo.js
import React from 'react';
import { observer } from 'mobx-react';
const AddTodo = () => {
const [inputValue, setInputValue] = React.useState('');
const handleKeyPress = (e) => {
if (e.key === 'Enter') {
TodoStore.addTodo(inputValue);
setInputValue('');
}
};
return (
<div>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyPress={handleKeyPress}
/>
</div>
);
};
export default observer(AddTodo);
Étape 5 : Mise en place des composants dans App.js
// App.js
import React from 'react';
import TodoList from './TodoList';
import AddTodo from './AddTodo';
const App = () => {
return (
<div>
<h1>Todo List</h1>
<AddTodo />
<TodoList />
</div>
);
};
export default App;
Étape 6 : Exécution du projet
npm start
Erreurs frequentes et debugging
Erreur 1 : Error: Invariant Violation: Objects are not valid as a React child (found: object with keys {type, target}). Did you accidentally try to render an object instead of the value of an attribute?
Cause : Vous essayez de rendre un objet au lieu d'une chaîne de caractères.
// ❌ Mauvais
return <div>{todo}</div>;
// ✅ Correct
return <div>{todo.text}</div>;
Erreur 2 : TypeError: Cannot read property 'length' of undefined
Cause : Vous essayez d'accéder à la propriété length d'une valeur qui n'est pas définie.
// ❌ Mauvais
@computed get todoCount() {
return this.todos.length;
}
// ✅ Correct
@computed get todoCount() {
return this.todos ? this.todos.length : 0;
}
Erreur 3 : Invariant Violation: Objects are not valid as a React child (found: object with keys {type, target}). Did you accidentally try to render an object instead of the value of an attribute?
Cause : Vous essayez de rendre un objet au lieu d'une chaîne de caractères.
// ❌ Mauvais
return <div>{todo}</div>;
// ✅ Correct
return <div>{todo.text}</div>;
Pour aller plus loin
- Async Actions : Apprenez à gérer les actions asynchrones avec MobX et React.
- MobX-Devtools : Utilisez les outils de développement MobX pour déboguer et visualiser l'état de votre application en temps réel.
- Migrer d'un gestionnaire d'état existant : Découvrez comment migrer une application React utilisant un autre gestionnaire d'état vers MobX.
Défi pratique
Créez un simple blog avec des articles qui peuvent être ajoutés, modifiés et supprimés. Utilisez MobX pour gérer l'état du blog et les afficher dans une liste.