Arrêtez de faire ces erreurs de composants
La vérité est que les composants sont d'une simplicité trompeuse. Il est facile de commencer : définissez une fonction, renvoyez du JSX et arrêtez-la. Mais écrire des composants propres, maintenables et agréables à utiliser ? C’est un tout autre jeu de balle.
Sans nous en rendre compte, nous créons des composants qui sont :
- Trop gros pour être compris d'un seul coup d'œil.
- Péniblement difficile à tester.
- Si étroitement couplés qu’ils sont impossibles à réutiliser.
- Lent en raison de mauvaises décisions de performance.
Dans cet article, je vais vous expliquer les erreurs les plus courantes commises par les développeurs avec les composants React. Plus important encore, je vais vous montrer comment les réparer sans détruire l'intégralité de votre application.
Que vous débutiez ou que vous ayez des années d'expérience, ces conseils vous aideront à écrire des composants qui ne sont pas seulement fonctionnels, mais agréables à entretenir.
L'anti-modèle « Tout composant »
Parlons de l’erreur classique que nous avons tous commise : le composant tout. Vous l'avez vu : cela commence petit et innocent, peut-être sous la forme d'un simple formulaire ou d'un tableau de bord. Avancez un peu, et maintenant il gère l'état, gère les appels d'API, formate les données et éventuellement prépare votre café du matin.
// Please, no more of this const UserDashboard = () => { const [userData, setUserData] = useState(null); const [orders, setOrders] = useState([]); const [notifications, setNotifications] = useState([]); const [settings, setSettings] = useState({}); const [isEditing, setIsEditing] = useState(false); const [activeTab, setActiveTab] = useState('profile'); // 15 separate useEffects // 10 different event handlers // Multiple conditional renders // 300+ lines of chaos };
Cela vous semble familier ?
Comment savoir si vous êtes coupable
Votre composant est peut-être devenu un « composant tout » si :
- Surcharge d'état : Vous suivez plus de 3 à 4 éléments d'état distincts.
- Défilement sans fin : Vous passez trop de temps à rechercher des fonctions ou une logique spécifiques.
- Globation des dépendances : Vos dépendances useEffect ressemblent à votre liste de courses hebdomadaire.
- Déni de fonctionnalité : Vous n'arrêtez pas de vous dire qu'une seule fonctionnalité de plus ne fera pas de mal.
Le décomposer
La solution ? Au lieu d'un seul composant, divisez les responsabilités en éléments plus petits et ciblés.
// A cleaner, smarter approach const UserDashboard = () => { return ( <div> <UserProfile /> <OrderHistory /> <NotificationCenter /> <UserSettings /> </div> ); };
Principe clé : Logique > Mise en page
Lors de la refactorisation, ne cassez pas les composants en fonction de leur apparence à l'écran. Divisez-les par responsabilité. Posez-vous la question : cette fonctionnalité mérite-t-elle son propre composant ? S'il gère quelque chose de distinct, comme les profils utilisateur ou l'historique des commandes, c'est probablement le cas.
Conseil : Un bon composant fait une chose et la fait bien. Si vous avez du mal à décrire son objectif en une seule phrase, il y a de fortes chances qu'il essaie d'en faire trop.
L'enfer du forage d'hélices
Parlons du jeu pas si amusant de « passer les accessoires ». Si vous avez déjà fait passer le même accessoire à travers plusieurs composants juste pour atteindre un enfant profondément imbriqué, vous avez été coincé dans l'enfer du forage d'accessoires.
// Please, no more of this const UserDashboard = () => { const [userData, setUserData] = useState(null); const [orders, setOrders] = useState([]); const [notifications, setNotifications] = useState([]); const [settings, setSettings] = useState({}); const [isEditing, setIsEditing] = useState(false); const [activeTab, setActiveTab] = useState('profile'); // 15 separate useEffects // 10 different event handlers // Multiple conditional renders // 300+ lines of chaos };
Cette approche n’est pas seulement ennuyeuse : elle crée des problèmes à long terme. Imaginez devoir renommer l'accessoire utilisateur. Du coup, vous le mettez à jour à cinq endroits ou plus. Pire encore, vous finissez par lier des composants à des données qu'ils n'utilisent même pas.
Comment résoudre ce problème
Pas besoin de jouer à la patate chaude avec vos accessoires. Voici deux solutions pratiques pour éviter complètement de percer.
1. Utiliser le contexte pour les données partagées
Si une donnée est accessible dans différentes parties de votre application, l'API Context de React peut simplifier les choses.
// A cleaner, smarter approach const UserDashboard = () => { return ( <div> <UserProfile /> <OrderHistory /> <NotificationCenter /> <UserSettings /> </div> ); };
2. Utilisez la composition pour la flexibilité
Au lieu de forcer les accessoires à travers les couches, restructurez les composants afin qu'ils ne transmettent que ce qui est nécessaire.
// This is exhausting const App = () => { const [user, setUser] = useState({}); return ( <Layout user={user}> <Sidebar user={user}> <Navigation user={user}> <UserMenu user={user} /> </Navigation> </Sidebar> </Layout> ); };
Principaux points à retenir
Le contexte fonctionne bien pour les données à l'échelle de l'application, telles que les informations utilisateur, les thèmes ou les paramètres globaux. Cependant, ce n’est pas toujours la meilleure option : n’en abusez pas. Pour un état localisé, demandez-vous si la structure de vos composants peut être ajustée pour éviter complètement le perçage.
L'objectif est de rendre vos composants clairs et maintenables. Éviter le forage d'hélices vous fera gagner du temps, de la frustration et d'innombrables maux de tête sur la route.
Pièges d’optimisation prématurée
Vous avez probablement entendu cette célèbre citation selon laquelle l'optimisation prématurée est la racine de tous les maux. Eh bien, bienvenue dans le mal au niveau des composants. Je parle de ces moments où nous essayons de tout rendre réutilisable avant même de savoir si nous en aurons besoin deux fois.
Voici à quoi cela ressemble habituellement :
const UserContext = createContext(); const App = () => { const [user, setUser] = useState({}); return ( <UserContext.Provider value={user}> <Layout> <Sidebar> <Navigation /> </Sidebar> </Layout> </UserContext.Provider> ); }; // Use it only where needed const UserMenu = () => { const user = useContext(UserContext); return <div>{user.name}</div>; };
Laissez vos composants évoluer naturellement. Construisez pour ce dont vous savez avoir besoin aujourd’hui. Si de nouvelles exigences surviennent, ajoutez des fonctionnalités lorsque vous pouvez les justifier clairement. Une optimisation prématurée fait perdre du temps, ajoute de la complexité et est rarement payante.
Rappelez-vous : Le principe YAGNI (You Aren’t Gonna Need It) s’applique également aux composants. Les meilleures abstractions surviennent lorsque vous avez réellement rencontré les problèmes qu’elles résolvent. La sur-ingénierie peut sembler proactive, mais la simplicité l'emporte à chaque fois.
Mauvaise gestion des effets secondaires
Voici un exemple classique de mauvaise gestion des effets. Vous semblez familier ?
// Focused components for better clarity const Navigation = ({ children }) => { return <nav>{children}</nav>; }; // Pass data only where required const App = () => { const user = useUser(); return ( <Layout> <Navigation> <UserMenu user={user} /> </Navigation> </Layout> ); };
Erreurs et correctifs courants
1) Récupération de données désordonnée
Une mauvaise gestion des données crée plus de bugs qu’elle n’en résout. Voici une approche plus propre :
// Behold, the over-engineered button const Button = ({ children, variant = 'primary', size = 'medium', isFullWidth = false, isDisabled = false, isLoading = false, leftIcon, rightIcon, onClick, customClassName, style, loadingText = 'Loading...', tooltipText, animationType, // ... 10 more props }) => { // 50 lines of prop processing logic return ( <button className={generateComplexClassNames()} > <h3> Why This Hurts </h3> <ul> <li>Your “simple” button now requires an instruction manual.</li> <li>Most of those 15+ props will never be used.</li> <li>Making updates becomes risky because you have to account for endless combinations.</li> <li>Writing tests becomes painful, with a hundred possible scenarios to consider.</li> </ul> <h3> Better Approach: </h3> <p>Instead of building for every imaginable scenario, start small and let your components grow as needed.<br> </p> <pre class="brush:php;toolbar:false">// Start simple const Button = ({ children, onClick, variant = 'primary' }) => { return ( <button className={`btn btn-${variant}`} onClick={onClick} > {children} </button> ); } // Create specific buttons when you actually need them const LoadingButton = ({ isLoading, children, ...props }) => { return ( <Button {...props}> {isLoading ? 'Loading...' : children} </Button> ); }
2) Oublier le nettoyage
Nettoyez toujours après vous :
const UserProfile = ({ userId }) => { const [user, setUser] = useState(null); const [posts, setPosts] = useState([]); // Dependency array woes useEffect(() => { fetchUserData(userId); fetchUserPosts(userId); // No cleanup? Yikes. }, []); // eslint-disable-line react-hooks/exhaustive-deps // Multiple effects, all tangled useEffect(() => { const subscription = subscribeToUserStatus(userId); }, [userId]); // Cleanup? What cleanup? useEffect(() => { const interval = setInterval(checkNotifications, 5000); }, []); };
3) Ignorer les conditions de course
Évitez les demandes qui se chevauchent avec cette technique :
// Improved version const UserProfile = ({ userId }) => { const { data: user, isLoading } = useQuery( ['user', userId], () => fetchUserData(userId) ); // Keep concerns separate const { data: posts } = useQuery( ['posts', userId], () => fetchUserPosts(userId), { enabled: !!user } ); };
Conseils rapides
- Réfléchissez avant d'utiliser useEffect : parfois, vous n'en aurez peut-être pas besoin du tout.
- Gardez-vous concentré : un effet doit gérer une responsabilité.
- Toujours nettoyer : les abonnements, les intervalles et les auditeurs d'événements nécessitent une attention particulière.
- Utilisez les bons outils : les bibliothèques comme React Query simplifient la récupération et la mise en cache des données.
- Ne trichez pas avec eslint-disable : corrigez les problèmes de dépendance au lieu de les masquer.
Angles morts des performances
Parlons de ces problèmes de performances sournois. Ils sont du genre à passer inaperçus parce que tout semble bien, jusqu’à ce que ce ne soit plus le cas. Découvrons ces coupables silencieux et voyons comment y remédier.
Le problème
Voici un composant présentant quelques pièges subtils en termes de performances :
// Please, no more of this const UserDashboard = () => { const [userData, setUserData] = useState(null); const [orders, setOrders] = useState([]); const [notifications, setNotifications] = useState([]); const [settings, setSettings] = useState({}); const [isEditing, setIsEditing] = useState(false); const [activeTab, setActiveTab] = useState('profile'); // 15 separate useEffects // 10 different event handlers // Multiple conditional renders // 300+ lines of chaos };
Pouvez-vous repérer les problèmes ? Décomposons-les.
Corrections
1) Mémorisez les calculs coûteux
Au lieu de tout recalculer à chaque rendu, utilisez useMemo pour mettre en cache les résultats :
// A cleaner, smarter approach const UserDashboard = () => { return ( <div> <UserProfile /> <OrderHistory /> <NotificationCenter /> <UserSettings /> </div> ); };
Cela évite de recalculer les données et de recréer les gestionnaires d'événements à chaque rendu. Cela évite également les nouveaux rendus inutiles des composants enfants avec mémo.
2) Mises à jour efficaces de l'état
Une mauvaise gestion de l’État peut également nuire aux performances. Voici une meilleure façon de gérer les mises à jour telles que les résultats de recherche :
// This is exhausting const App = () => { const [user, setUser] = useState({}); return ( <Layout user={user}> <Sidebar user={user}> <Navigation user={user}> <UserMenu user={user} /> </Navigation> </Sidebar> </Layout> ); };
L'anti-rebond garantit que nous ne récupérons pas de données à chaque frappe, ce qui réduit les appels d'API et les rendus inutiles.
Conseils rapides sur les performances
- N'abusez pas de la mémorisation : optimisez uniquement lorsque cela en vaut la peine.
- Évitez les fonctions en ligne : les références stables améliorent les performances.
- Gardez les accessoires prévisibles : les accessoires peu profonds et stables aident les composants à rester efficaces.
- Séparez les grandes listes : des outils tels que React-window peuvent gérer de gros ensembles de données avec élégance.
- Rapprochez l’état : gérez l’état uniquement là où il est réellement nécessaire.
- Profil avec DevTools : mesurez toujours avant d'optimiser.
Conclusion
Construire des composants n’est pas compliqué, mais soyons réalistes : il est facile de prendre de mauvaises habitudes. J'ai commis chacune de ces erreurs (et je le fais parfois encore). Ce n'est pas grave. Ce qui compte, c'est de les détecter tôt, de les corriger et d'éviter une base de code grossière.
Liste de contrôle rapide pour de meilleurs composants
✅ Responsabilité unique : Si vous ne pouvez pas résumer le travail de votre composant en une phrase, il est temps de le décomposer.
✅ Gestion des accessoires : passer les accessoires de couches en couches ? Envisagez plutôt d'utiliser le contexte ou de tirer parti de la composition.
✅ État et effets : gardez les effets concentrés, nettoyez-les correctement et laissez les outils modernes gérer la récupération de données complexes.
✅ Performance : n'optimisez pas pour le plaisir : mesurez d'abord. Utilisez intelligemment des outils tels que memo, useMemo et useCallback en cas de besoin.
✅ Commencez simplement : résolvez les problèmes que vous rencontrez maintenant, pas ceux que vous pourriez avoir un jour.
Les meilleurs composants ne sont ni tape-à-l’œil ni trop intelligents : ce sont ceux que votre équipe peut lire et maintenir sans gémir six mois plus tard.
Rappelez-vous : ce ne sont pas des règles strictes, juste des lignes directrices. Vous les casserez parfois, et c’est parfaitement bien. L’objectif n’est pas la perfection : il s’agit de créer des éléments qui ne vous amèneront pas à remettre en question vos choix de carrière lorsque vous les revisiterez plus tard.
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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds











Python convient plus aux débutants, avec une courbe d'apprentissage en douceur et une syntaxe concise; JavaScript convient au développement frontal, avec une courbe d'apprentissage abrupte et une syntaxe flexible. 1. La syntaxe Python est intuitive et adaptée à la science des données et au développement back-end. 2. JavaScript est flexible et largement utilisé dans la programmation frontale et côté serveur.

Le passage de C / C à JavaScript nécessite de s'adapter à la frappe dynamique, à la collecte des ordures et à la programmation asynchrone. 1) C / C est un langage dactylographié statiquement qui nécessite une gestion manuelle de la mémoire, tandis que JavaScript est dynamiquement typé et que la collecte des déchets est automatiquement traitée. 2) C / C doit être compilé en code machine, tandis que JavaScript est une langue interprétée. 3) JavaScript introduit des concepts tels que les fermetures, les chaînes de prototypes et la promesse, ce qui améliore la flexibilité et les capacités de programmation asynchrones.

Les principales utilisations de JavaScript dans le développement Web incluent l'interaction client, la vérification du formulaire et la communication asynchrone. 1) Mise à jour du contenu dynamique et interaction utilisateur via les opérations DOM; 2) La vérification du client est effectuée avant que l'utilisateur ne soumette les données pour améliorer l'expérience utilisateur; 3) La communication de rafraîchissement avec le serveur est réalisée via la technologie AJAX.

L'application de JavaScript dans le monde réel comprend un développement frontal et back-end. 1) Afficher les applications frontales en créant une application de liste TODO, impliquant les opérations DOM et le traitement des événements. 2) Construisez RestulAPI via Node.js et Express pour démontrer les applications back-end.

Comprendre le fonctionnement du moteur JavaScript en interne est important pour les développeurs car il aide à écrire du code plus efficace et à comprendre les goulots d'étranglement des performances et les stratégies d'optimisation. 1) Le flux de travail du moteur comprend trois étapes: analyse, compilation et exécution; 2) Pendant le processus d'exécution, le moteur effectuera une optimisation dynamique, comme le cache en ligne et les classes cachées; 3) Les meilleures pratiques comprennent l'évitement des variables globales, l'optimisation des boucles, l'utilisation de const et de locations et d'éviter une utilisation excessive des fermetures.

Python et JavaScript ont leurs propres avantages et inconvénients en termes de communauté, de bibliothèques et de ressources. 1) La communauté Python est amicale et adaptée aux débutants, mais les ressources de développement frontal ne sont pas aussi riches que JavaScript. 2) Python est puissant dans les bibliothèques de science des données et d'apprentissage automatique, tandis que JavaScript est meilleur dans les bibliothèques et les cadres de développement frontaux. 3) Les deux ont des ressources d'apprentissage riches, mais Python convient pour commencer par des documents officiels, tandis que JavaScript est meilleur avec MDNWEBDOCS. Le choix doit être basé sur les besoins du projet et les intérêts personnels.

Les choix de Python et JavaScript dans les environnements de développement sont importants. 1) L'environnement de développement de Python comprend Pycharm, Jupyternotebook et Anaconda, qui conviennent à la science des données et au prototypage rapide. 2) L'environnement de développement de JavaScript comprend Node.js, VScode et WebPack, qui conviennent au développement frontal et back-end. Le choix des bons outils en fonction des besoins du projet peut améliorer l'efficacité du développement et le taux de réussite du projet.

C et C jouent un rôle essentiel dans le moteur JavaScript, principalement utilisé pour implémenter des interprètes et des compilateurs JIT. 1) C est utilisé pour analyser le code source JavaScript et générer une arborescence de syntaxe abstraite. 2) C est responsable de la génération et de l'exécution de bytecode. 3) C met en œuvre le compilateur JIT, optimise et compile le code de point chaud à l'exécution et améliore considérablement l'efficacité d'exécution de JavaScript.
