Débuter avec Redux Connecter Redux avec React

Ceci est la troisième partie de la série intitulée Getting Started With Redux. Dans ce didacticiel, nous allons apprendre à connecter un magasin Redux à React. Redux est une bibliothèque indépendante qui fonctionne avec toutes les bibliothèques et infrastructures front-end populaires. Et cela fonctionne parfaitement avec React en raison de son approche fonctionnelle.

Vous n'avez pas besoin de suivre les parties précédentes de cette série pour que ce tutoriel ait un sens. Si vous êtes ici pour en savoir plus sur l'utilisation de React avec Redux, vous pouvez utiliser la récapitulation rapide ci-dessous, puis consulter le code de la partie précédente et commencer à partir de là.. 

Récapitulation rapide

Dans le premier article, nous avons découvert le flux de travail Redux et répondu à la question, Pourquoi Redux? Nous avons créé une application de démonstration très basique et vous avons montré comment les différents composants des actions Redux, des réducteurs et du magasin sont connectés..

Dans l'article précédent, nous avons commencé à créer une application de liste de contacts qui vous permet d'ajouter des contacts, puis de les afficher sous forme de liste. Nous avons créé un magasin Redux pour notre liste de contacts et nous avons ajouté quelques réducteurs et actions. Nous avons tenté d’envoyer des actions et d’extraire le nouvel état à l’aide de méthodes de stockage telles que store.dispatch () et store.getState ().

À la fin de cet article, vous aurez appris:

  1. la différence entre les composants du conteneur et les composants de présentation
  2. à propos de la bibliothèque react-redux
  3. comment lier réagir et redux en utilisant relier()
  4. comment envoyer des actions en utilisant mapDispatchToProps
  5. comment récupérer l'état en utilisant mapStateToProps

Le code du didacticiel est disponible sur GitHub dans le référentiel react-redux-demo. Prenez le code du v2 branche et utilisez-le comme point de départ pour ce tutoriel. Si vous êtes curieux de savoir à quoi ressemble l'application à la fin de ce didacticiel, essayez la branche v3. Commençons.

Conception d'une hiérarchie de composants: composants intelligents et composants intelligents

C'est un concept dont vous avez probablement déjà entendu parler, mais examinons rapidement la différence entre les composants intelligents et les composants stupides. Rappelons que nous avons créé deux répertoires distincts pour les composants, l’un nommé conteneurs / et l'autre Composants/. L’avantage de cette approche est que la logique de comportement est séparée de la vue..

Les composants de présentation sont dits muets car ils se soucient de leur apparence. Ils sont découplés de la logique métier de l'application et reçoivent les données et les rappels d'un composant parent exclusivement via des accessoires. Peu leur importe que votre application soit connectée à un magasin Redux si les données proviennent de l'état local du composant parent. 

Les composants de conteneur, quant à eux, traitent de la partie comportementale et doivent contenir un style et des balises DOM très limités. Ils transmettent les données qui doivent être restituées aux composants muets sous forme d'accessoires.. 

J'ai traité le sujet en profondeur dans un autre didacticiel, Composants à états contre états sans état dans React.

Passons maintenant, voyons comment nous allons organiser nos composants.

Composants de présentation

Voici les composants de présentation que nous allons utiliser dans ce tutoriel. 

composants / AddContactForm.jsx

importer Réagir de 'réagir'; const AddContactForm = (onInputChange, onFormSubmit) => ( 
/ * Certains codes omis pour des raisons de concision * /
) export default AddContactForm;

Ceci est un formulaire HTML pour ajouter un nouveau contact. Le composant reçoit onInputChange et onFormSubmit callbacks comme accessoires. le onInputChange événement est déclenché lorsque la valeur d'entrée change et onFormSubmit quand le formulaire est soumis.

components / ContactList.jsx

const ContactList = (props) => return ( 
    props.contactList.map ((contact) =>
  • )
) export default ContactList;

Ce composant reçoit un tableau d'objets de contact en tant qu'accessoires, d'où son nom Liste de contacts. Nous utilisons le Array.map () méthode pour extraire les détails de contact individuels, puis transmettre ces données à .

composants / ContactCard.jsx

const ContactCard = (contact) => return ( 
contact.photo! == non défini ? contact.name : contact.name
contact.name + "+ contact.surname
/ * Certains codes omis pour des raisons de concision * /
) ExportCard par défaut;

Ce composant reçoit un objet de contact et affiche le nom et l'image du contact. Pour des applications pratiques, il peut être judicieux d'héberger des images JavaScript dans le cloud..

Composants du conteneur

Nous allons également construire des composants de conteneur de base.

conteneurs / Contacts.jsx

la classe Contacts étend Component constructeur (props) super (props); this.returnContactList = this.returnContactList.bind (this);  returnContactList () // Récupère la liste de contacts du magasin render () return ( 

) exporter les contacts par défaut;

le returnContactList () function récupère le tableau d'objets contact et le transmet au composant ContactList. Puisque returnContactList () récupère les données du magasin, nous laisserons cette logique vide pour le moment.

conteneurs / AddContacts.jsx

la classe AddContact étend Component constructor (props) super (props); / * La liaison de fonction va ici. Omis par souci de brièveté * / showAddContactBox () / * Logique permettant de basculer ContactForm * / handleInputChange (event) const target = event.target; valeur const = target.value; nom de const = target.name; / * Logique de traitement des modifications d'entrée * / handleSubmit (e) e.preventDefault (); / * Logique permettant de masquer le formulaire et de mettre à jour l'état * / / * Rend le AddContactForm * / renderForm () return ( 
) render () return (
/ * Une instruction conditionnelle va ici pour vérifier si le formulaire doit être affiché ou non * /
) export par défaut AddContact;

Nous avons créé trois méthodes de traitement de base, correspondant aux trois actions. Ils envoient tous des actions pour mettre à jour l'état. Dans la méthode de rendu, nous avons laissé de côté la logique d'affichage / masquage du formulaire, car nous avons besoin d'extraire l'état. 

Voyons maintenant comment lier réagir et redux ensemble

La bibliothèque react-redux

Les liaisons de réaction ne sont pas disponibles dans Redux par défaut. Vous devrez d'abord installer une bibliothèque supplémentaire appelée react-redux. 

npm install --save react-redux 

La bibliothèque n’exporte que deux API dont vous devez vous souvenir, une composant et une fonction d'ordre supérieur connu sous le nom relier()

Le composant fournisseur

Des bibliothèques telles que Redux doivent rendre les données du magasin accessibles à l’ensemble de l’arborescence des composants React, à partir du composant racine. Le modèle Fournisseur permet à la bibliothèque de transmettre les données de haut en bas. Le code ci-dessous montre comment le fournisseur ajoute par magie l'état à tous les composants de l'arborescence des composants.. 

Code de démonstration

importer fournisseur de 'react-redux' ReactDOM.render (   , document.getElementById ('root'))

Toute l'application doit avoir accès au magasin. Nous encapsulons donc le fournisseur autour du composant d'application, puis nous ajoutons les données dont nous avons besoin au contexte de l'arborescence. Les descendants du composant ont alors accès aux données. 

le relier() Méthode 

Maintenant que nous avons à condition de le magasin à notre application, nous devons connecter React au magasin. Le seul moyen de communiquer avec le magasin consiste à envoyer des actions et à récupérer l'état. Nous avons déjà utilisé store.dispatch () envoyer des actions et store.getState () pour récupérer le dernier instantané de l'état. le relier() vous permet de faire exactement cela, mais avec l'aide de deux méthodes connues sous le nom mapDispatchToProps et mapStateToProps. J'ai démontré ce concept dans l'exemple ci-dessous:

Code de démonstration

importer connect à partir de 'react-redux' const AddContact = (newContact, addContact) => return ( 
newContact.name
newContact.email
newContact.phone
Êtes-vous sûr de vouloir ajouter ce contact? Oui
) const mapStateToProps = state => return newContact: state.contacts.newContact const mapDispatchToProps = dispatch => return addContact: () => dispatch (addContact ()) export par défaut (mapStateToProps, mapDispatchToProps )(Ajouter le contact)

mapStateToProps et mapDispatchToProps tous deux renvoient un objet et la clé de cet objet devient un accessoire du composant connecté. Par exemple, state.contacts.newContact est mappé sur props.newContact. Le créateur d'action ajouter le contact() est mappé sur props.addContact.  

Mais pour que cela fonctionne, vous avez besoin de la dernière ligne de l'extrait de code ci-dessus.. 

exporter la connexion par défaut (mapStateToProps, mapDispatchToProps) (AddContact)

Au lieu d'exporter le Ajouter le contact composant directement, nous exportons un composant connecté. Le connect fournit ajouter le contact et nouveau contact comme accessoires à la composant. 

Comment connecter React et Redux

Ensuite, nous allons couvrir les étapes que vous devez suivre pour connecter React et Redux.

Installer la bibliothèque react-redux

Installez la bibliothèque react-redux si ce n'est déjà fait. Vous pouvez utiliser NPM ou Yarn pour l'installer. 

npm installer react-redux --save 

Fournir le magasin à votre composant d'application

Créez le magasin d'abord. Ensuite, rendez l’objet magasin accessible à votre arborescence des composants en le transmettant comme accessoire à .

index.js

importer Réagir de 'réagir'; importer render de 'react-dom'; importer Fournisseur de 'react-redux' import App de './App'; importer configureStore de './store' const store = configureStore (); rendre(   , document.getElementById ('root'))

Connecter les conteneurs React à Redux

La fonction connect est utilisée pour lier les conteneurs React à Redux. Cela signifie que vous pouvez utiliser la fonctionnalité de connexion pour:

  1. abonnez-vous au magasin et associez son état à vos accessoires
  2. actions d'expédition et mapper les rappels d'expédition dans vos accessoires

Une fois que vous avez connecté votre application à Redux, vous pouvez utiliser this.props d'accéder à l'état actuel et d'envoyer des actions. Je vais démontrer le processus sur le Ajouter le contact composant. Ajouter le contact doit envoyer trois actions et obtenir l’état de deux propriétés à partir du magasin. Regardons le code.

Tout d'abord, importer relier dans AddContact.jsx.

importer connect de 'react-redux'; 

Deuxièmement, créez deux méthodes: mapStateToProps et mapDispatchToProps.

fonction mapStateToProps (state) return isHidden: state.ui.isAddContactFormHidden, newContact: state.contacts.newContact fonction mapDispatchToProps (dispatch) return onFormSubmit: (newContact) => (dispatch (addContact); , onInputChange: (nom, valeur) => dispatch (handleInputChange (nom, valeur)); , onToggle: () => dispatch (toggleContactForm ()); 

mapStateToProps reçoit l'état du magasin en tant qu'argument. Il retourne un objet qui décrit comment l'état du magasin est mappé dans vos accessoires.. mapDispatchToProps retourne un objet similaire qui décrit comment les actions de dispatch sont mappées sur vos accessoires. 

Enfin, nous utilisons relier lier le Ajouter le contact composant aux deux fonctions comme suit:

exporter la connexion par défaut (mapStateToProps, mapDispatchToProps) (AddContact) 

Mettre à jour les composants du conteneur pour utiliser les accessoires

Les accessoires du composant sont maintenant équipés pour lire l'état à partir des actions de magasin et d'envoi. La logique de handeInputChange, handleSubmit et showAddContactBox devrait être mis à jour comme suit:

 showAddContactBox () const onToggle = = this.props; onToggle ();  handleInputChange (event) const target = event.target; valeur const = target.value; nom de const = target.name; const onInputChange = this.props; onInputChange (nom, valeur);  handleSubmit (e) e.preventDefault (); this.props.onToggle (); this.props.onFormSubmit (); 

Nous avons défini les méthodes de gestionnaire, mais il manque encore une partie, l’instruction conditionnelle à l’intérieur du rendre une fonction.

render () return ( 
this.props.isHidden === false? this.renderForm ():
)

Si est caché est faux, le formulaire est rendu. Sinon, un bouton est rendu. 

Affichage des contacts

Nous avons terminé la partie la plus difficile. Il ne reste plus maintenant qu’à afficher ces contacts sous forme de liste. le Contacts conteneur est le meilleur endroit pour cette logique. 

importer Réagir, Composant de 'réagir'; importer connect de 'react-redux'; / * Importation de composant omise par souci de brièveté * / class Contact de composant Component constructeur (props) super (props); this.returnContactList = this.returnContactList.bind (this);  returnContactList () return this.props.contactList;  render () return ( 


) function mapStateToProps (state) return contactList: state.contacts.contactList, exporter la connexion par défaut (mapStateToProps, null) (Contact);

Nous avons suivi la procédure décrite ci-dessus pour connecter le composant Contacts au magasin Redux. le mapStateToProps fonction mappe l'objet de magasin à la liste de contacts les accessoires. Nous utilisons ensuite connect pour lier la valeur props au composant Contact. Le second argument de la connexion est null car nous n'avons aucune action à distribuer. Cela complète l'intégration de notre application avec l'état du magasin Redux. 

Quoi ensuite?

Dans le prochain article, nous examinerons plus en détail le middleware et commencerons à distribuer des actions impliquant la récupération de données du serveur. Partagez votre opinion dans les commentaires!