Maison >interface Web >js tutoriel >Redux vs Mobx: Quel est le meilleur pour votre projet?
Pour de nombreux développeurs JavaScript, la plus grande plainte auprès de Redux est la quantité de code de chaudière nécessaire pour implémenter les fonctionnalités. Une meilleure alternative est MOBX qui fournit des fonctionnalités similaires mais avec un code moindre à écrire.
Pour les débutants MOBX, jetez un coup d'œil à cette introduction écrite par le créateur de Mobx. Vous pouvez également parcourir ce tutoriel pour acquérir une certaine expérience pratique.
Le but de cet article est d'aider les développeurs JavaScript à décider lequel de ces deux solutions de gestion des États est la meilleure pour leurs projets. J'ai migré ce projet Crud Redux vers MOBX à utiliser comme exemple dans cet article. Je vais d'abord discuter des avantages et des inconvénients de l'utilisation de MOBX, puis je vais démontrer des échantillons de code réels des deux versions pour montrer la différence.
Le code des projets mentionnés dans cet article peut être trouvé sur GitHub:
Si vous aimez ce post, vous aimerez peut-être également vous inscrire à SitePoint Premium et regarder notre cours sur le travail avec des formulaires en utilisant React et Redux.
Tout d'abord, regardons ce qu'ils ont tous les deux en commun. Ils:
Voyons maintenant les principales différences entre Redux et Mobx.
Pour un débutant, vous pouvez apprendre à utiliser MOBX en seulement 30 minutes. Une fois que vous avez appris les bases, c'est tout. Vous n'avez pas besoin d'apprendre quoi que ce soit de nouveau. Avec Redux, les bases sont également faciles. Cependant, une fois que vous commencerez à créer des applications plus complexes, vous devrez traiter:
Avec Mobx, toutes ces situations sont «magiquement» prises en charge. Vous n'avez pas besoin de bibliothèques supplémentaires pour gérer de telles situations.
Pour implémenter une fonctionnalité dans Redux, vous devez mettre à jour au moins quatre artefacts. Cela inclut la rédaction de code pour les réducteurs, les actions, les conteneurs et les composants. C'est particulièrement ennuyeux si vous travaillez sur un petit projet. MOBX vous oblige uniquement à mettre à jour au moins deux artefacts (c'est-à-dire le magasin et le composant de vue).
Si vous préférez écrire du code orienté objet, vous serez heureux de savoir que vous pouvez utiliser la POO pour implémenter la logique de gestion de l'État avec MOBX. Grâce à l'utilisation de décorateurs tels que @Observable et @Observer, vous pouvez facilement rendre vos composants et magasins JavaScript simples. Si vous préférez la programmation fonctionnelle, aucun problème - cela est également pris en charge. Redux, en revanche, est fortement adapté aux principes de programmation fonctionnelle. Cependant, vous pouvez utiliser la bibliothèque Redux-Connect-Decorator si vous voulez une approche basée sur la classe.
Dans la plupart des applications JavaScript, vous vous retrouverez à travailler avec des données relationnelles ou imbriquées. Pour pouvoir l'utiliser dans un magasin Redux, vous devrez d'abord le normaliser. Ensuite, vous devez écrire un peu plus de code pour gérer le suivi des références dans des données normalisées.
Dans MOBX, il est recommandé de stocker vos données sous une forme dénormalisée. MOBX peut garder une trace des relations pour vous et renforcera automatiquement les changements. En utilisant des objets de domaine pour stocker vos données, vous pouvez vous référer directement à d'autres objets de domaine définis dans d'autres magasins. De plus, vous pouvez utiliser (@) des décorateurs et des modificateurs calculés pour les observables pour résoudre facilement des défis de données complexes.
redux est un cadre qui fournit des directives strictes sur la façon dont vous écrivez le code d'état. Cela signifie que vous pouvez facilement écrire des tests et développer un code maintenable. Mobx est une bibliothèque et n'a aucune règle sur la façon de l'implémenter. Le danger avec cela est qu'il est très facile de prendre des raccourcis et d'appliquer des correctifs rapides qui peuvent conduire à un code inaccessible.
Le code interne de MOBX gère «comme par magie» beaucoup de logique pour rendre votre application réactive. Il y a un domaine invisible où vos données passent entre le magasin et votre composant, ce qui rend difficile le débogage lorsque vous avez un problème. Si vous modifiez l'état directement dans les composants, sans utiliser @Actions, vous aurez du mal à identifier la source d'un bogue.
Dans le développement de logiciels, les nouvelles tendances émergentes apparaissent tout le temps. En quelques années, les techniques logicielles actuelles peuvent rapidement perdre l'élan. Pour le moment, plusieurs solutions sont en concurrence avec Redux et Mobx. Quelques exemples sont Relay / Apollo & GraphQL, Alt.JS et Jumpsuit. Toute de ces technologies a le potentiel de devenir la plus populaire. Si vous voulez vraiment savoir lequel vous convient le mieux, vous devrez tous les essayer.
Assez de théorie, regardons le code. Tout d'abord, nous comparons comment chaque version est en train de bootstrap.
Version Redux: Dans Redux, nous définissons d'abord notre magasin, puis nous le transmettons à l'application via le fournisseur. Nous devrons également définir des logiciels de middle redux-thunk et redux-promis pour gérer les fonctions asynchrones. Le redux-devtools-extension nous permet de déboguer notre magasin en mode de voyage dans le temps.
<span>// src/store.js </span><span>import <span>{ applyMiddleware, createStore }</span> from "redux"; </span><span>import thunk from "redux-thunk"; </span><span>import promise from "redux-promise-middleware"; </span><span>import <span>{ composeWithDevTools }</span> from 'redux-devtools-extension'; </span><span>import rootReducer from "./reducers"; </span> <span>const middleware = composeWithDevTools(applyMiddleware(promise(), thunk)); </span> <span>export default createStore(rootReducer, middleware); </span> <span>------------------------------------------------------------------------------- </span> <span>// src/index.js </span>… <span>ReactDOM.render( </span> <span><span><span><BrowserRouter</span>></span> </span><span> <span><span><Provider</span> store<span>={store}</span>></span> </span><span> <span><span><App</span> /></span> </span><span> <span><span></Provider</span>></span> </span><span> <span><span></BrowserRouter</span>></span>, </span> <span>document.getElementById('root') </span><span>); </span>
Version MOBX: Dans MOBX, nous devons configurer plusieurs magasins. Dans ce cas, j'utilise un seul magasin, que j'ai placé dans une collection nommée Allstores. Un fournisseur est ensuite utilisé pour passer la collection de magasins à l'application.
Comme mentionné précédemment, Mobx n'a pas besoin de bibliothèques externes pour gérer les actions asynchrones, d'où moins de lignes. Cependant, nous avons besoin du MOBX-Remotedev pour se connecter à l'outil de débogage redux-devtools-extension.
<span>// src/stores/index.js </span><span>import remotedev from 'mobx-remotedev'; </span><span>import <span>Store</span> from './store'; </span> <span>const contactConfig = { </span> <span>name:'Contact Store', </span> <span>global: true, </span> <span>onlyActions:true, </span> <span>filters: { </span> <span>whitelist: <span>/fetch<span>|update|create|Event|entity|entities|handleErrors</span>/</span> </span> <span>} </span><span>}; </span> <span>const contactStore = new Store('api/contacts'); </span> <span>const allStores = { </span> <span>contactStore: remotedev(contactStore, contactConfig) </span><span>}; </span> <span>export default allStores; </span> <span>------------------------------------------------------------------------------- </span> <span>// src/index.js </span>… <span>ReactDOM.render( </span> <span><span><span><BrowserRouter</span>></span> </span><span> <span><span><Provider</span> stores<span>={allStores}</span>></span> </span><span> <span><span><App</span> /></span> </span><span> <span><span></Provider</span>></span> </span><span> <span><span></BrowserRouter</span>></span>, </span> <span>document.getElementById('root') </span><span>); </span>
La quantité de code ici est à peu près à peu près la même dans les deux versions. Mobx a moins d'instructions d'importation.
Version Redux: Dans Redux, l'état et les actions sont transmis aux accessoires à l'aide de la fonction connect () de React-Redux.
<span>// src/pages/contact-form-page.js </span>… <span>// accessing props </span> <span><span><span><ContactForm</span> </span></span><span> <span>contact<span>={this.props.contact}</span> </span></span><span> <span>loading<span>={this.props.loading}</span> </span></span><span> <span>onSubmit<span>={this.submit}</span> </span></span><span> <span>/></span> </span>… <span>// function for injecting state into props </span><span>function mapStateToProps(state) { </span> <span>return { </span> <span>contact: state.contactStore.contact, </span> <span>errors: state.contactStore.errors </span> <span>} </span><span>} </span> <span>// injecting both state and actions into props </span><span>export default connect(mapStateToProps, { newContact, </span> saveContact<span>, </span> fetchContact<span>, </span> updateContact <span>})(ContactFormPage); </span>
Version MOBX: Dans Mobx, nous injectons simplement la collection de magasins. Nous utilisons @Inject en haut d'un conteneur ou d'une classe de composants pour ce faire. Cela rend les magasins disponibles dans les accessoires, ce qui nous permet d'accéder à un magasin spécifique et de le transmettre à un composant enfant. L'état et les actions sont accessibles via des propriétés de l'objet de magasin, donc pas besoin de les passer séparément comme avec le cas dans Redux.
<span>// src/pages/contact-form-page.js </span> … @<span>inject("stores") @observer // injecting store into props </span><span>class ContactFormPage extends Component { </span>… <span>// accessing store via props </span> <span>const { contactStore:store } = this.props.stores; </span> <span>return ( </span> <span><span><span><ContactForm</span> </span></span><span> <span>store<span>={store}</span> </span></span><span> <span>form<span>={this.form}</span> </span></span><span> <span>contact<span>={store.entity}</span> </span></span><span> <span>/></span> </span> <span>) </span>… <span>} </span>
La version MOBX semble être plus facile à lire. Cependant, nous pouvons utiliser les décorateurs redux-Connect pour simplifier le code redux. Dans ce cas, il n'y aura pas de gagnant clair.
Pour garder cet article maigre, je vais vous montrer un échantillon de code pour une seule action.
Version Redux: Dans Redux, nous devons définir des actions et des réducteurs.
<span>// src/store.js </span><span>import <span>{ applyMiddleware, createStore }</span> from "redux"; </span><span>import thunk from "redux-thunk"; </span><span>import promise from "redux-promise-middleware"; </span><span>import <span>{ composeWithDevTools }</span> from 'redux-devtools-extension'; </span><span>import rootReducer from "./reducers"; </span> <span>const middleware = composeWithDevTools(applyMiddleware(promise(), thunk)); </span> <span>export default createStore(rootReducer, middleware); </span> <span>------------------------------------------------------------------------------- </span> <span>// src/index.js </span>… <span>ReactDOM.render( </span> <span><span><span><BrowserRouter</span>></span> </span><span> <span><span><Provider</span> store<span>={store}</span>></span> </span><span> <span><span><App</span> /></span> </span><span> <span><span></Provider</span>></span> </span><span> <span><span></BrowserRouter</span>></span>, </span> <span>document.getElementById('root') </span><span>); </span>
Version MOBX: Dans Mobx, la logique de l'action et du réducteur se fait dans une classe. J'ai défini une action asynchrone qui appelle une autre entité d'action récupérée après la réception de la réponse.
Puisque Mobx utilise le style OOP, la classe de magasin définie ici a été refactorisée pour permettre une création facile de plusieurs magasins à l'aide du constructeur de classe. Par conséquent, le code démontré ici est un code de base qui n'est pas lié à un magasin de domaine particulier.
<span>// src/stores/index.js </span><span>import remotedev from 'mobx-remotedev'; </span><span>import <span>Store</span> from './store'; </span> <span>const contactConfig = { </span> <span>name:'Contact Store', </span> <span>global: true, </span> <span>onlyActions:true, </span> <span>filters: { </span> <span>whitelist: <span>/fetch<span>|update|create|Event|entity|entities|handleErrors</span>/</span> </span> <span>} </span><span>}; </span> <span>const contactStore = new Store('api/contacts'); </span> <span>const allStores = { </span> <span>contactStore: remotedev(contactStore, contactConfig) </span><span>}; </span> <span>export default allStores; </span> <span>------------------------------------------------------------------------------- </span> <span>// src/index.js </span>… <span>ReactDOM.render( </span> <span><span><span><BrowserRouter</span>></span> </span><span> <span><span><Provider</span> stores<span>={allStores}</span>></span> </span><span> <span><span><App</span> /></span> </span><span> <span><span></Provider</span>></span> </span><span> <span><span></BrowserRouter</span>></span>, </span> <span>document.getElementById('root') </span><span>); </span>
Croyez-le ou non, la logique définie dans les deux versions effectuent les mêmes tâches, qui sont:
Dans Redux, nous avons utilisé 33 lignes de code. Dans MOBX, nous avons utilisé environ 14 lignes de code pour obtenir le même résultat! Un avantage majeur de la version MOBX est que vous pouvez réutiliser le code de base dans presque toutes les classes de magasin de domaine avec peu ou pas de modification. Cela signifie que vous pouvez créer votre application plus rapidement.
Pour créer des formes dans Redux, j'ai utilisé la forme redux. Dans MOBX, j'ai utilisé MOBX-REACT-FORM. Les deux bibliothèques sont matures et vous aident à gérer facilement la logique du formulaire. Personnellement, je préfère la forme de MOBX-réaction, car elle vous permet de valider les champs via des plugins. Avec Redux-Form, vous écrivez votre propre code de validation, soit importer un package de validation pour gérer la validation pour vous.
Un petit inconvénient avec MOBX est que vous ne pouvez pas accéder directement à certaines fonctions dans des objets observables car ce ne sont pas des objets JavaScript vraiment simples. Heureusement, ils ont fourni la fonction TOJS () que vous pouvez utiliser pour convertir des objets observables en objets JavaScript simples.
clairement, vous pouvez voir que la base de code de Mobx est beaucoup plus maigre. En utilisant le style OOP et de bonnes pratiques de développement, vous pouvez rapidement créer des applications. L'inconvénient majeur est qu'il est très facile d'écrire un code pauvre et incompétent.
Redux, en revanche, est plus populaire et bien adapté pour construire des projets importants et complexes. Il s'agit d'un cadre strict avec des garanties garantissant que chaque développeur écrit du code facile à tester et à entretenir. Cependant, il n'est pas bien adapté aux petits projets.
Malgré les inconvénients de Mobx, vous pouvez toujours construire de grands projets si vous suivez de bonnes pratiques. Selon les mots d'Albert Einstein, «rendre tout aussi simple que possible, mais pas plus simple».
J'espère que j'ai fourni suffisamment d'informations pour indiquer clairement s'il faut migrer vers MOBX ou s'en tenir à Redux. En fin de compte, la décision dépend du type de projet sur lequel vous travaillez et des ressources à votre disposition.
Chargement du joueur…redux et mobx sont tous deux des bibliothèques de gestion de l'État, mais elles diffèrent dans leurs philosophies et approches de base. Redux suit un modèle de gestion d'état strict et prévisible basé sur l'architecture de flux. Il a un seul magasin et les modifications d'état sont apportées par des actions et des réducteurs. D'un autre côté, Mobx adopte une approche plus flexible et intuitive. Il permet à plusieurs magasins et les modifications d'état sont effectuées directement par le biais d'actions.
redux est souvent favorisé pour les applications à grande échelle en raison de son prévisible et Gestion transparente de l'État. Le modèle strict d'actions et de réducteurs facilite le suivi des changements d'état, qui peuvent être cruciaux dans des applications complexes. Cependant, Mobx, avec son approche plus flexible, peut également être utilisé efficacement dans des applications à grande échelle, en particulier lorsque les développeurs préfèrent un style de codage moins réduit et plus simple.
redux a une courbe d'apprentissage plus abrupte par rapport à MOBX. Il faut comprendre les concepts des actions, des réducteurs et du magasin, et comment ils interagissent les uns avec les autres. D'un autre côté, MOBX est généralement considéré comme plus facile à saisir car il utilise des concepts de programmation plus familiers comme les observables et les actions, et il nécessite moins de code de passe-partout.
redux nécessite du middleware comme redux-thunk ou redux-saga pour gérer les actions asynchrones. Ces middleware permettent des actions pour expédier d'autres actions ou pour retarder la répartition d'une action. Mobx, en revanche, peut gérer directement les actions asynchrones sans avoir besoin de middleware supplémentaire.
Oui, Redux et Mobx peuvent être utilisé ensemble dans une seule application. Cependant, cela n'est pas communément fait car cela peut entraîner une complexité inutile. Il est généralement recommandé de choisir l'un ou l'autre en fonction des besoins et des contraintes spécifiques de votre projet.
redux a un avantage clair en matière de essai. Ses changements d'état prévisibles et ses fonctions pures (réducteurs) facilitent le test. Mobx, bien que pas aussi simple à tester en raison de sa nature plus dynamique, peut toujours être testé efficacement à l'aide d'outils comme JEST.
Redux et Mobx ont de bonnes caractéristiques de performance et peuvent gérer efficacement les grands arbres d'État. Cependant, MOBX peut avoir un avantage dans certains scénarios en raison de son système d'observabilité à grains fins, qui met à jour uniquement les composants qui sont directement affectés par un changement d'état.
redux a une communauté plus large et un écosystème plus mature par rapport à MOBX. Il y a plus de ressources disponibles pour l'apprentissage de Redux et plus de bibliothèques tierces conçues pour travailler avec elle. Cependant, Mobx a gagné en popularité et sa communauté se développe.
MOBX pourrait être un meilleur choix pour les projets où les développeurs Préférez un style de codage plus simple et moins réducteur, ou lorsque le projet nécessite un contrôle à grains fins sur les mises à jour d'état. C'est aussi un bon choix lorsque l'équipe est plus à l'aise avec les concepts de programmation orientés objet, car MOBX les exploite fortement.
Redux pourrait être un meilleur choix pour les applications à grande échelle où la prévisibilité et la transparence des changements d'État sont cruciales. C'est aussi un bon choix lorsque l'équipe est à l'aise avec les concepts de programmation fonctionnelle, car Redux les exploite fortement. De plus, l'écosystème mature de Redux et la grande communauté peuvent être un facteur décisif.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!