ReactJS - Portails : Une Porte vers de Nouvelles Dimensions dans vos Applications React
Bonjour, aspirants développeurs React ! Aujourd'hui, nous allons entreprendre un voyage passionnant à la découverte des React Portails. Imaginez que vous construisez une maison (votre application React), et soudain vous vous rendez compte que vous avez besoin d'un passage secret pour transporter quelque chose d'une pièce à une autre sans passer par le grand couloir. C'est essentiellement ce que les React Portails font pour vos composants !
Qu'est-ce que les React Portails ?
Les React Portails offrent une manière de premier ordre pour rendre les enfants dans un nœud DOM qui existe en dehors de la hiérarchie DOM du composant parent. En termes plus simples, c'est comme créer un trou de ver qui vous permet de rendre un composant à un autre endroit dans l'arbre DOM, même s'il fait toujours partie de votre hiérarchie de composants React.
Pourquoi avons-nous besoin de Portails ?
Vous pourriez vous demander, "Pourquoi ne puis-je pas simplement rendre mon composant où je veux ?" Eh bien, dans la plupart des cas, vous pouvez ! Mais il y a des situations où les Portails sont pratiques :
- Dialogues modaux
- Infobulles (tooltips)
- Menus flottants
- Widgets qui ont besoin de sortir de leur conteneur
Plongons plus profondément dans le fonctionnement des Portails et comment les utiliser.
Créer Votre Premier Portail
Pour créer un Portail, nous utilisons la méthode ReactDOM.createPortal()
. Voici un exemple de base :
import React from 'react';
import ReactDOM from 'react-dom';
function MyPortalComponent() {
return ReactDOM.createPortal(
<h1>J'ai été rendu ailleurs !</h1>,
document.getElementById('portal-root')
);
}
Dans cet exemple, nous créons un Portail qui rend un élément <h1>
dans un nœud DOM avec l'ID 'portal-root'. Ce nœud devrait exister quelque part dans votre HTML, en dehors de l'élément racine de votre application React principale.
Décomposons la méthode ReactDOM.createPortal()
:
- Le premier argument est l'élément React que vous souhaitez rendre.
- Le second argument est le nœud DOM où vous souhaitez le rendre.
Un Exemple du Monde Réel : un Dialogue Modal
Crçons un exemple plus pragmatique - un dialogue modal qui apparaît au-dessus du contenu de votre application.
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
function Modal({ isOpen, onClose, children }) {
if (!isOpen) return null;
return ReactDOM.createPortal(
<div className="modal-overlay">
<div className="modal-content">
{children}
<button onClick={onClose}>Fermer</button>
</div>
</div>,
document.getElementById('modal-root')
);
}
function App() {
const [isModalOpen, setIsModalOpen] = useState(false);
return (
<div>
<h1>Bienvenue dans Mon App</h1>
<button onClick={() => setIsModalOpen(true)}>Ouvrir le Modal</button>
<Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)}>
<h2>Ceci est un Modal</h2>
<p(Il est rendu en dehors de l'arbre principal React !</p>
</Modal>
</div>
);
}
Dans cet exemple, nous avons créé un composant réutilisable Modal
qui utilise un Portail pour rendre son contenu. Le composant App
contrôle la visibilité du modal en utilisant le hook useState
de React.
Décomposons ce qui se passe :
- Le composant
Modal
vérifie s'il doit être ouvert (isOpen
prop). - Si ouvert, il crée un Portail qui rend son contenu dans l'élément 'modal-root'.
- Le contenu du modal inclut un bouton de fermeture qui déclenche la prop
onClose
. - Dans le composant
App
, nous utilisons le state pour contrôler la visibilité du modal.
Événements qui Remontent à travers les Portails
Un aspect fascinant des Portails est que même s'ils peuvent rendre du contenu n'importe où dans l'arbre DOM, les événements remontent toujours dans l'arbre React comme prévu. Voici un exemple :
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
function Parent() {
const [clicks, setClicks] = useState(0);
const handleClick = () => {
setClicks(clicks + 1);
};
return (
<div onClick={handleClick}>
<h1>Clics : {clicks}</h1>
<Portal>
<Child />
</Portal>
</div>
);
}
function Portal({ children }) {
return ReactDOM.createPortal(
children,
document.getElementById('portal-root')
);
}
function Child() {
return <button>Cliquez sur moi !</button>;
}
Dans cet exemple, cliquer sur le bouton à l'intérieur du Portail déclenchera toujours le gestionnaire d'événement dans le composant Parent, incrémentant le compteur de clics. Ce comportement est extrêmement utile car il maintient la propagation d'événements attendue, indépendamment de l'endroit où le composant est réellement rendu dans le DOM.
Meilleures Pratiques et Considérations
Lors de l'utilisation des Portails, gardez ces points à l'esprit :
- Accessibilité : Assurez-vous que le contenu de votre Portail est accessible, en particulier pour les lecteurs d'écran.
- Gestion des événements : Souvenez-vous que les événements remontent dans l'arbre React, pas dans l'arbre DOM.
- Stylisation : Le contenu du Portail peut nécessiter des considérations de stylisation séparées.
- Nettoyage : N'oubliez pas de nettoyer vos Portails lorsque le composant est démonté.
Méthodes des Portails
Voici un tableau des méthodes clés liées aux React Portails :
Méthode | Description |
---|---|
ReactDOM.createPortal(child, container) |
Crée un portail. child est n'importe quel enfant rendable React, et container est un élément DOM. |
ReactDOM.unmountComponentAtNode(container) |
Supprime un composant monté du DOM et nettoie ses gestionnaires d'événements et son state. |
Conclusion
Les React Portails sont une fonctionnalité puissante qui vous permet de vous échapper de la hiérarchie de composants traditionnelle lors du rendu. Ils sont particulièrement utiles pour créer des modals, des infobulles et d'autres éléments UI qui ont besoin de "sortir" visuellement de leurs conteneurs.
Souvenez-vous, avec un grand pouvoir vient une grande responsabilité ! Utilisez les Portails avec sagesse, et songez toujours à l'impact sur la structure et l'accessibilité de votre application.
Bonne programmation, et puissent vos Portails toujours ouvrir de nouvelles dimensions dans vos applications React !
Credits: Image by storyset