Les Modèles de Conception en React
16 juil. 2024
Table des matières:
- Introduction
- Layout Components
- Controlled vs Uncontrolled Components
- Higher-Order Components (HOC)
- Compound Components
- Render Props
- Custom Hooks
- Conclusion
Introduction
Les modèles de conception (design patterns) en React sont des solutions efficaces aux défis courants du développement d’applications. Ils permettent de structurer le code de manière plus maintenable et réutilisable, tout en facilitant la résolution de problèmes. Dans cet article, nous explorerons quelques-uns des modèles de conception les plus courants et utiles en React.
Layout Components
Les Layout Components aident à organiser d’autres composants en différentes sections de la page, ce qui améliore la structure visuelle et l’expérience utilisateur.
- Écrans Partagés (Split Screens)
Les écrans partagés permettent d’organiser plusieurs composants dans différentes sections de la page, améliorant ainsi la structure visuelle de l’application. Cela rend l’expérience utilisateur plus simple à comprendre et facilite la navigation. Au lieu de passer les composants en tant que props, il est préférable de les passer en tant que composants enfants (extraction des composants), ce qui rend le code plus lisible et modulaire.
Exemple
import styled from "styled-components"; const Container = styled.div` display: flex;`; const Pane = styled.div` flex: ${(props) => props.weight};`; //composant d'ecran partageconst SplitScreen = ({ children, leftWeight = 1, rightWeight = 1 }) => { const [left, right] = children; return ( <Container> <Pane weight={leftWeight}>{left}</Pane> <Pane weight={rightWeight}>{right}</Pane> </Container> );};
Les écrans partagés sont particulièrement utiles dans les tableaux de bord, où vous pouvez avoir une barre latérale de navigation et une zone de contenu principale.
- Listes et Éléments de Liste
Les composants de liste sont utilisés pour afficher des collections de données de manière organisée. Le composant de liste itère sur les données et rend chaque élément de la liste à l’aide du composant d’élément de liste.
Exemple
// Composant d'élément de listeconst ListItem = ({ item }) => { const { name, price, description, rating } = item; return ( <> <h3>{name}</h3> <p>{price}</p> <h3>Description:</h3> <p>{description}</p> <p>Average Rating: {rating}</p> </> );}; // Composant de listeconst List = ({ items}) => { return ( <> {items.map((item, i) => ( <ListItem key={i} item={item} /> ))} </> );};
Controlled vs Uncontrolled Components
Les composants contrôlés et non contrôlés en React offrent différentes approches pour gérer les éléments de formulaire, chacun avec ses propres avantages.
- Controlled Components
Les composants contrôlés sont ceux où l’état de l’élément du formulaire est contrôlé par le state du composant React. Ils permettent une validation du formulaire pendant que l’utilisateur tape et offrent une liaison bidirectionnelle entre la valeur des entrées et les variables d’état.
Exemple
import { useState, useEffect } from "react"; // Composant de formulaire contrôléexport const ControlledForm = () => { const [nameInputError, setNameInputError] = useState(""); const [name, setName] = useState(""); const [age, setAge] = useState(""); const [hairColor, setHairColor] = useState(""); useEffect(() => { if (name.length < 2) { setNameInputError("Name must be two or more characters"); } else { setNameInputError(""); } }, [name]); return ( <form> {nameInputError && <p>{nameInputError}</p>} <input name="name" type="text" placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} /> <input name="age" type="number" placeholder="Age" value={age} onChange={(e) => setAge(Number(e.target.value))} /> <input name="hairColor" type="text" placeholder="Hair Color" value={hairColor} onChange={(e) => setHairColor(e.target.value)} /> <button>Submit</button> </form> );}; function App() { return ( <div> <ControlledForm /> </div> );} export default App;
- Uncontrolled Components
Les composants non contrôlés utilisent une référence (ref) pour accéder directement aux valeurs des éléments du formulaire dans le DOM. L’état de l’élément du formulaire est géré par le DOM lui-même, plutôt que par le state du composant React.
Exemple
import React from "react"; const UncontrolledForm = () => { const nameInput = React.createRef(); const ageInput = React.createRef(); const hairColorInput = React.createRef(); const handleSubmit = (e) => { console.log(nameInput.current.value); console.log(ageInput.current.value); console.log(hairColorInput.current.value); e.preventDefault(); }; return ( <form onSubmit={handleSubmit}> <input name="name" type="text" placeholder="Name" ref={nameInput} /> <input name="age" type="number" placeholder="Age" ref={ageInput} /> <input name="hairColor" type="text" placeholder="Hair Color" ref={hairColorInput} /> <input type="submit" value="Submit" /> </form> );}; function App() { return <UncontrolledForm />;} export default App;
Higher-Order Components (HOC)
Les composants d’ordre supérieur (HOC) sont une technique avancée de réutilisation de la logique des composants dans React. Un HOC est une fonction qui prend un composant et retourne un nouveau composant avec des fonctionnalités étendues.
Exemple
import React, { useState, useEffect } from "react";import axios from "axios"; const withUser = (Component, userId) => { return (props) => { const [user, setUser] = useState(null); useEffect(() => { (async () => { const response = await axios.get(`/users/${userId}`); setUser(response.data); })(); }); return <Component {...props} user={user} />; };}; const UserInfo = ({ user }) => { const { name, age, hairColor, hobbies } = user || {}; return user ? ( <> <h3>{name}</h3> <p>Age: {age} years</p> <p>Hair Color: {hairColor}</p> <h3>Hobbies:</h3> <ul> {hobbies.map((hobby) => ( <li key={hobby}>{hobby}</li> ))} </ul> </> ) : ( <p>Loading...</p> );}; const UserInfoWithLoader = withUser(UserInfo, "234"); function App() { return <UserInfoWithLoader />;} export default App;
Compound Components
Les composants de composition permettent de créer des composants plus flexibles en divisant la logique d’un composant en plusieurs sous-composants.
const Button = ({ size, color, text, ...props }) => { return ( <button style={{ padding: size === "large" ? "32px" : "8px", fontSize: size === "large" ? "32px" : "16px", backgroundColor: color, }} {...props} > {text} </button> );}; const DangerButton = (props) => { return <Button {...props} color="red" />;}; const BigSuccessButton = (props) => { return <Button {...props} size="large" color="green" />;}; function App() { return ( <> <DangerButton text="Don't do it!" /> <BigSuccessButton text="Yes!!!" /> </> );} export default App;
Render Props
La technique des Render Props consiste à passer une fonction en tant que prop à un composant pour contrôler ce qu’il rend. Cela permet de partager la logique de rendu entre les composants de manière plus flexible que les HOC.
Exemple
import React, { useState } from "react"; //composant de filtrage avec comme props un composantconst FilterableList = ({ items, render }) => { const [filter, setFilter] = useState(""); const filteredItems = items.filter((item) => item.toLowerCase().includes(filter.toLowerCase()) ); return ( <div> <input type="text" placeholder="Search..." value={filter} onChange={(e) => setFilter(e.target.value)} /> {render(filteredItems)} </div> );}; //composant de propsconst ItemList = ({ items }) => ( <ul> {items.map((item, index) => ( <li key={index}>{item}</li> ))} </ul>); //utilisation de ItemList comme propsconst App = () => { const items = [ "Apple", "Banana", "Cherry", "Date", "Elderberry", "Fig", "Grape", ]; return ( <FilterableList items={items} render={(filteredItems) => <ItemList items={filteredItems} />} /> );}; export default App;
Custom Hooks
Les custom hooks sont des fonctions JavaScript qui combinent les hooks useState
et useEffect
et même le useRef
de React pour encapsuler la logique d’état réutilisable dans plusieurs composants. Ils permettent de partager facilement la logique entre les composants.
Exemple
import { useState, useEffect } from "react";import axios from "axios"; const useCurrentUser = () => { const [user, setUser] = useState(null); useEffect(() => { (async () => { const response = await axios.get("/current-user"); setUser(response.data); })(); }, []); return user;};
Conclusion
Les modèles de conception en React offrent des solutions efficaces pour structurer et réutiliser le code, rendant les applications plus maintenables et évolutives. En comprenant et en utilisant ces modèles, vous pouvez améliorer la performance et la qualité de vos applications React.
Partager cet article:
Coach à Bakeli School of Technology