Liste de contrôle pour la revue de code React : améliorez la sécurité et les performances
›Blog›Liste de contrôle pour la revue de code React : améliorez la sécurité et les performances
14 Juillet, 2025
53 lecture min
Pour les applications React complexes, une audit de code et une revue de qualité par des tiers sont bien plus qu’un simple plus : c’est un investissement essentiel. Sauter cette étape, ou n’effectuer que des revues superficielles, peut entraîner une cascade de problèmes par la suite : incapacité à monter en charge, vulnérabilités de sécurité et dette technique qui étouffe l’innovation et fait exploser les coûts de développement.
C’est pourquoi nous avons élaboré cette liste de contrôle complète pour la revue de code React. Chez Redwerk, nous développons des logiciels personnalisés et effectuons des revues de code depuis 2005. Ce guide s’appuie sur des années d’expérience pratique dans plusieurs secteurs, tels que l’e-gouvernement, l’e-commerce, l’e-learning, les médias et le divertissement, et plus encore.
Ainsi, que vous vous prépariez à lancer une application basée sur React, que vous vous attaquiez à des problèmes de performance, ou que vous visiez à vous préparer proactivement pour la diligence raisonnable initiée par un investisseur, cette liste de contrôle de revue de code React JS vous aidera à identifier les problèmes et à trouver des solutions.
La préparation préalable à l’examen garantit que l’environnement est prêt, que les dépendances sont mises à jour et que le code est dans des conditions optimales pour un examen de code React efficace et approfondi. Cette étape se concentre sur l’organisation du projet, la définition d’objectifs clairs et la garantie que tous les outils, configurations et documentations sont en place pour faciliter un processus d’examen fluide.
Définir la portée et les objectifs :
Décrire clairement les objectifs et les domaines sur lesquels portera l’examen, tels que la qualité du code, les performances, la sécurité ou une fonctionnalité spécifique (comme une fonctionnalité ou un module particulier).
Déterminer si l’examen couvrira l’ensemble de l’application, des composants spécifiques ou des fonctionnalités clés.
Définir des critères de succès mesurables, tels que l’amélioration de la lisibilité du code, la réduction des bugs potentiels ou l’optimisation des performances.
Vérifier la configuration du projet et les dépendances :
S’assurer que toutes les dépendances sont à jour en exécutant npm install ou yarn install. Vérifier également qu’aucun package obsolète ou vulnérable n’est utilisé.
Examiner le fichier package.json pour en vérifier l’exactitude et éviter les packages inutiles ou obsolètes.
Vérifier que le projet utilise la dernière version stable de React et de toutes les bibliothèques associées (par exemple, React Router, Redux, etc.) afin d’assurer la compatibilité avec les meilleures pratiques modernes.
Vérifier que toutes les bibliothèques tierces sont correctement configurées et que leur utilisation est nécessaire.
Confirmer la configuration de l’environnement :
S’assurer que l’environnement de développement est correctement configuré avec tous les outils requis, tels qu’ESLint pour l’analyse statique du code, Prettier pour le formatage, et toute autre extension ou linter spécifique à React.
Vérifier que le projet s’exécute correctement dans les environnements de développement et de production – cela inclut l’exécution de l’application localement (npm start, yarn start) et sa compilation pour la production (npm run build, yarn build) sans aucune erreur ni avertissement.
S’assurer que les paramètres spécifiques à l’environnement (par exemple, les points d’accès API, les variables d’environnement) sont gérés correctement à l’aide de fichiers .env ou d’outils de configuration, afin d’éviter de coder en dur des valeurs directement dans le code.
Examiner et optimiser la couverture des tests :
S’assurer que des tests unitaires sont en place pour tous les composants et fonctions critiques, en utilisant des bibliothèques de test telles que Jest et React Testing Library.
S’assurer que la couverture des tests est complète, couvrant les interactions utilisateur clés, la gestion de l’état et les cas limites.
Examiner la structure de la suite de tests pour s’assurer que les tests sont organisés logiquement et qu’il n’y a pas de chevauchement – les tests unitaires doivent se concentrer sur des fonctionnalités isolées, tandis que les tests d’intégration peuvent vérifier l’interaction des composants.
Vérifier que la suite de tests s’exécute sans erreur ni échec (npm test, yarn test) et que des assertions significatives sont faites.
S’assurer que tous les tests sont descriptifs, en utilisant des noms qui expliquent clairement la fonctionnalité testée.
Exécuter les outils d’analyse statique de code :
S’assurer que les outils d’analyse statique de code tels qu’ESLint et Prettier sont correctement configurés pour appliquer un style de code cohérent et identifier les problèmes potentiels tels que les variables inutilisées, les erreurs de syntaxe ou les « code smells ».
Exécuter les outils d’analyse de code et examiner les résultats avant de commencer l’examen afin de résoudre tout problème lié au style ou à l’analyse statique.
S’assurer que les règles des meilleures pratiques sont appliquées de manière cohérente dans tout le projet.
Vérifier que les résultats de l’analyse statique et du formatage du code sont intégrés dans le pipeline CI/CD pour appliquer les normes de qualité du code à chaque pull request ou fusion de code.
Vérifier et organiser la documentation :
S’assurer que la documentation pertinente du projet est à jour, y compris un README clair qui explique comment configurer, compiler et exécuter le projet, ainsi que toutes les instructions de configuration spécifiques pour les examinateurs.
Vérifier que les commentaires en ligne et la documentation du code (par exemple, JSDoc) sont utilisés si nécessaire pour expliquer la logique complexe, les arguments de fonction ou le comportement attendu, afin de faciliter la compréhension du code par les examinateurs.
Examiner toute documentation d’API ou intégration de services tiers pour s’assurer qu’elles sont correctement documentées et accessibles aux examinateurs qui pourraient avoir besoin d’un contexte supplémentaire pendant l’examen.
Examiner le flux de travail Git et les branches de code :
S’assurer que le projet suit un flux de travail Git bien défini (par exemple, Gitflow, feature branching) pour maintenir les modifications de code organisées et gérables pendant l’examen.
Examiner les branches de fonctionnalités pour s’assurer qu’elles sont correctement fusionnées.
Vérifier que toutes les pull requests ou branches de fonctionnalités ouvertes sont rebasées ou fusionnées avec les derniers changements de la branche principale, afin d’éviter les conflits ou le code obsolète pendant le processus d’examen.
S’assurer que des messages de commit significatifs sont utilisés, décrivant clairement l’objectif de chaque modification.
Valider les dépendances et les API externes :
S’assurer que toutes les dépendances externes (par exemple, les API, les services tiers) sont correctement simulées à des fins de test et d’examen.
S’assurer qu’il n’y a pas de dépendances fortes sur des services externes qui pourraient échouer ou se casser pendant l’examen.
Examiner la configuration des appels API, en s’assurant qu’une gestion des erreurs est en place pour les requêtes échouées et que les données sensibles telles que les clés API ou les jetons sont stockées en toute sécurité à l’aide de variables d’environnement.
Vérifier que les bibliothèques et API tierces sont utilisées efficacement, et envisager des alternatives si la dépendance peut être remplacée par des fonctionnalités React intégrées ou des options plus légères.
Configurer et tester le pipeline de construction et de déploiement :
S’assurer que le pipeline CI/CD est correctement configuré pour construire, tester et déployer automatiquement l’application ; cela inclut les tests automatisés, l’analyse statique du code et le linting pour détecter les problèmes rapidement.
Examiner la configuration de construction (par exemple, Webpack, Vite) pour s’assurer que la construction de production est optimisée pour les performances, avec des fonctionnalités telles que le tree shaking et le code splitting activées.
Vérifier que le pipeline de déploiement fonctionne correctement, déployant automatiquement les modifications sur les environnements de staging ou de production sans erreur.
Préparer les données et les scénarios de test :
S’assurer que les données et les scénarios de test sont préparés pour l’examen – des ensembles de données exemples ou des données fictives pour tester différentes parties de l’application, telles que les formulaires, les API et les interactions utilisateur.
Examiner et configurer des cas de test réalistes pour les composants clés, en s’assurant qu’ils couvrent divers scénarios d’entrée (par exemple, valides, invalides, cas limites) et qu’ils sont bien documentés pour que l’examinateur puisse les suivre.
S’assurer que les flux utilisateur et le comportement fonctionnel peuvent être facilement reproduits pendant l’examen, afin d’aider les examinateurs à comprendre comment le code interagit avec le reste de l’application.
Lisibilité et cohérence du code
Garantir la lisibilité et la cohérence du code est essentiel pour maintenir une base de code React propre et maintenable. Un code lisible et cohérent permet une collaboration plus fluide, un débogage plus facile et une intégration plus rapide des nouveaux développeurs. Voici comment vous assurer que vos développeurs React JS ont fait un excellent travail.
Respectez des conventions de nommage cohérentes :
Assurez-vous que les composants, fonctions, variables et fichiers suivent des conventions de nommage cohérentes et significatives (utilisez PascalCase pour les noms de composants React et camelCase pour les fonctions, variables et hooks)
Vérifiez que les noms de fichiers correspondent au composant ou à la fonction qu’ils exportent ; évitez les abréviations ou les noms trop génériques qui masquent l’objectif du code
Assurez la cohérence des noms pour les props et les variables d’état, en vous assurant qu’ils décrivent clairement les données qu’ils représentent (par exemple, isLoading, userList)
Maintenez des signatures de composants et de fonctions claires :
Assurez-vous que les signatures de fonctions et de composants sont simples et explicites, avec des noms de paramètres descriptifs
Assurez-vous qu’il n’y a pas de signatures de fonctions trop complexes avec des arguments excessifs, tandis que les paramètres liés sont regroupés dans des objets si nécessaire
Vérifiez que les props passées aux composants sont concises, en évitant les props inutiles ou redondantes qui encombrent la signature du composant
// Correct: uses clear and descriptive names
type UserCardProps = {
username: string;
age: number;
};
const UserCard: React.FC = ({ username, age }) => {
return (
{username}
Age: {age}
);
};
// Wrong: component name Card is too generic, prop names are unclear
const Card = ({ u, a }) => {
return (
{u}
Age: {a}
);
}
Utilisez des commentaires clairs et descriptifs :
Assurez-vous que les commentaires sont utilisés pour expliquer une logique non évidente, en particulier autour des règles métier ou des transitions d’état complexes
Vérifiez que les commentaires sont clairs et concis, fournissant un contexte précieux sans être trop verbeux
Assurez-vous qu’ils expliquent le « pourquoi » des décisions plutôt que de simplement indiquer ce que fait le code
Vérifiez que les commentaires en ligne sont à jour et pertinents par rapport au code qu’ils décrivent
// Correct: explains the purpose of the component
// Displays a user's profile information
const UserProfile = ({ name, age }: { name: string; age: number }) => (
{name}
Age: {age}
);
// Wrong: the comment repeats what the code already shows
// This is a UserProfile component
const UserProfile = ({ name, age }) => (
{name}
Age: {age}
);
Utilisation cohérente de la syntaxe et du formatage JSX :
Assurez-vous que la syntaxe JSX est cohérente, y compris l’indentation, l’espacement et le placement des attributs — utilisez le JSX sur une seule ligne pour les éléments courts et sur plusieurs lignes pour les éléments comportant plusieurs props ou enfants
Vérifiez que le JSX est correctement formaté avec une utilisation cohérente des balises auto-fermantes pour les éléments sans enfants (par exemple, au lieu de )
Assurez-vous que les props sont alignées et indentées de manière cohérente, améliorant la lisibilité des longs attributs JSX
// Correct: uses consistent indentation and proper spacing
const UserProfile = ({ name, age }: { name: string; age: number }) => (
{name}
Age: {age}
);
// Wrong: uses inconsistent indentation, making it harder to read
const UserProfile = ({name,age}) =>
{name}
Age: {age}
;
Assurez un formatage et un style de code cohérents :
Assurez-vous que le code suit un guide de style cohérent dans tout le projet, en utilisant des outils de formatage comme Prettier pour appliquer l’indentation, l’espacement et les sauts de ligne de manière cohérente
Vérifiez que la longueur des lignes est maintenue dans une limite raisonnable (par exemple, 80-100 caractères), garantissant que le code reste facile à lire sur divers appareils ou IDE
Vérifiez que les règles de linting du projet (par exemple, ESLint) sont suivies de manière cohérente pour éviter des différences inutiles ou des incohérences de formatage dans la base de code
Utilisez Prop Types ou TypeScript pour la sécurité des types :
Assurez-vous que les types PropTypes ou TypeScript sont utilisés de manière cohérente pour définir les types de props attendus par les composants, empêchant les erreurs d’exécution et améliorant la lisibilité du code
Vérifiez que les définitions de type sont claires et concises, avec des structures de données complexes ou des objets imbriqués correctement définis
Vérifiez que les valeurs par défaut pour les props optionnels sont définies, soit via defaultProps (pour les projets JavaScript), soit via le chaînage optionnel et les valeurs par défaut de TypeScript
Assurez-vous que les expressions JSX sont simples et faciles à suivre
Assurez-vous qu’il n’y a pas d’intégration de logique complexe directement dans JSX, car cela peut réduire la lisibilité
Vérifiez si les calculs ou la logique conditionnelle sont déplacés vers des fonctions d’aide ou des variables d’état si nécessaire
Examinez l’utilisation du rendu conditionnel (&&, ? :) pour vous assurer qu’il n’est pas trop imbriqué ou difficile à lire
Vérifiez si les conditions complexes sont décomposées en plusieurs expressions plus petites ou fonctions d’aide
Vérifiez que les éléments répétés (par exemple, le rendu de liste avec map) sont concis et clairement structurés
Vérifiez si les props key sont utilisées de manière appropriée pour garantir que React peut suivre efficacement les éléments de la liste
// Correct: moves complex logic out of JSX into a function
const getDiscountMessage = (price: number) => {
return price > 100 ? "You get a discount!" : "No discount available.";
};
const Product = ({ price }: { price: number }) => (
{getDiscountMessage(price)}
);
// Correct: stores ternary logic in a variable to improve readability
const Product = ({ price }: { price: number }) => (
const discountMessage = price > 100 ? "You get a discount!" : "No discount available.";
{discountMessage}
);
// Wrong: hard to read because of nested expressions inside JSX
const Product = ({ price }) => (
{price > 100 ? "You get a discount!" : "No discount available."}
);
Évitez le code redondant ou mort :
Assurez-vous que tout code commenté ou inutilisé est supprimé de la base de code
Examinez la logique conditionnelle ou les drapeaux de fonctionnalités qui peuvent laisser du code inutile dans les builds de production
Vérifiez que le code dupliqué est refactorisé en composants réutilisables ou en fonctions d’aide, favorisant la réutilisation du code et réduisant la charge de maintenance
Gérez de manière cohérente la déstructuration des props et de l’état :
Assurez-vous que la déstructuration est utilisée de manière cohérente lors de la manipulation des props et de l’état, améliorant la lisibilité en réduisant le besoin de références répétées (par exemple, props.user devient { user })
Vérifiez que la déstructuration est appliquée en haut du composant ou du corps de la fonction pour maintenir une structure propre et organisée
Assurez-vous qu’il n’y a pas de déstructuration directement dans JSX, ce qui peut réduire la lisibilité
// Correct: destructure in function parameters
const UserProfile = ({ name, age, location }) => {
return (
Une partie cruciale d’un audit de qualité de code est de s’assurer que les composants sont modulaires, réutilisables et bien organisés. Ceci est important car une architecture de composants bien structurée et réutilisable est la clé pour construire des applications React évolutives et maintenables. Lors d’une revue de code React, se concentrer sur la structure et la réutilisabilité des composants permet de garantir que votre application reste facile à étendre.
Assurez-vous que les composants respectent le principe de responsabilité unique :
Vérifiez que chaque composant a une responsabilité claire et unique et qu’il se concentre sur un seul élément de fonctionnalité
Assurez-vous que les composants ne sont pas responsables de trop de tâches (par exemple, rendu de l’interface utilisateur, gestion de la logique métier complexe et récupération des données en un seul endroit)
Examinez les composants volumineux et refactorisez-les en sous-composants plus petits s’ils gèrent plusieurs responsabilités
Assurez-vous que la logique métier est séparée du rendu de l’interface utilisateur
Assurez-vous que la logique complexe est gérée par des composants conteneurs ou avec état, tandis que les composants de présentation se concentrent uniquement sur l’affichage de l’interface utilisateur
// Correct: keeps single responsibility and reusability
type UserCardProps = {
name: string;
age: number;
};
const UserCard: React.FC = ({ name, age }) => (
Promouvoir la réutilisabilité avec des composants génériques :
S’assurer que les modèles d’interface utilisateur courants (par exemple, boutons, modales, champs de formulaire) sont encapsulés dans des composants génériques et réutilisables qui peuvent être utilisés dans différentes parties de l’application
Examiner les composants pour détecter les doublons et refactoriser les morceaux de code similaires en composants partagés ou en fonctions utilitaires
Vérifier qu’il n’y a pas de duplication de logique similaire à plusieurs endroits
Vérifier que les composants sont conçus en pensant à la flexibilité en utilisant des props pour personnaliser le comportement ou l’apparence
**Utilisez une hiérarchie et un imbrication de composants appropriés :**
Assurez-vous que les composants sont structurés dans une hiérarchie claire qui reflète la structure logique de l’application
Veillez à ce qu’il n’y ait pas d’imbrication profonde de composants, car cela peut rendre le code plus difficile à suivre et à maintenir
Examinez les relations entre les composants parents et enfants pour vous assurer que les données circulent naturellement des composants parents aux enfants via les props
Assurez-vous qu’il n’y a pas de « prop drilling » excessif (passage de props à travers plusieurs couches) en utilisant le contexte ou des bibliothèques de gestion d’état si nécessaire
Vérifiez que les composants réutilisables sont placés dans les répertoires appropriés (par exemple, /components/shared pour les composants communs) afin d’améliorer l’organisation et l’accessibilité dans l’ensemble du codebase
**Assurez une séparation claire entre les composants conteneurs et les composants de présentation :**
Assurez-vous que l’application sépare les composants conteneurs (qui gèrent l’état, la logique et la récupération des données) des composants de présentation (qui se concentrent sur le rendu de l’interface utilisateur)
Examinez les composants de présentation pour vous assurer qu’ils sont sans état et reçoivent toutes les données et actions nécessaires via les props, ce qui les rend faciles à réutiliser et à tester
Vérifiez que les composants conteneurs sont responsables de la gestion de l’état et de la récupération des données, tout en déléguant les tâches de rendu aux composants de présentation
**Privilégiez la composition à l’héritage :**
Assurez-vous que les composants sont construits en utilisant la composition plutôt que l’héritage, car React promeut un modèle de composition de composants, où des composants plus petits sont composés ensemble pour construire des interfaces utilisateur plus complexes
Examinez la manière dont les composants sont composés pour vous assurer que les blocs de construction réutilisables (par exemple, des wrappers de mise en page, des éléments d’interface utilisateur) sont efficacement combinés
Vérifiez que la prop children de React est utilisée lorsque cela est approprié pour passer du JSX en tant que contenu dans les composants, permettant une composition flexible sans codage en dur de la structure à l’intérieur des composants
// Correct: composition with 'children' is more clear and easy to extend
const Card = ({ title, children }) => {
return (
Éviter le codage en dur des styles, utiliser des Styled Components ou des CSS Modules :
S’assurer que le style est appliqué de manière cohérente à l’aide de bibliothèques CSS-in-JS comme Styled Components ou Emotion, ou en utilisant des CSS Modules pour maintenir les styles isolés et maintenables
Examiner l’utilisation des styles en ligne et des valeurs codées en dur dans JSX pour s’assurer qu’ils sont minimisés
Vérifier que les éléments d’interface utilisateur réutilisables (par exemple, boutons, champs de saisie) ont des styles cohérents dans toute l’application, améliorant ainsi la maintenabilité et l’expérience utilisateur
Garantir l’accessibilité dans les composants réutilisables :
S’assurer que les composants réutilisables sont accessibles par défaut, en suivant les meilleures pratiques telles que la fourniture d’attributs aria appropriés, d’étiquettes et de prise en charge de la navigation au clavier
Vérifier que les boutons, les éléments de formulaire et autres composants interactifs incluent les attributs nécessaires pour les rendre accessibles à tous les utilisateurs (par exemple, aria-label, role, tabIndex)
Vérifier que toute bibliothèque de composants réutilisables ou tout système de conception respecte les normes d’accessibilité, garantissant ainsi que l’application est inclusive et répond aux exigences d’accessibilité
// Correct: using aria labels & semantic elements
const IconButton = ({ icon, label, onClick }) => {
return (
{icon}
);
};
// Wrong: missing aria and wrong elements
const IconButton = ({ icon, onClick }) => {
return {icon};
};
// Correct: using label and id in forms
const TextInput = ({ label, id, ...props }) => {
return (
Utilisation appropriée des Hooks et de la gestion d’état React
L’utilisation efficace des Hooks et de la gestion d’état React garantit que les applications React restent prévisibles, maintenables et faciles à faire évoluer. Les Hooks sont un élément essentiel du développement React moderne, et la compréhension de la gestion appropriée de l’état assure de meilleures performances et un code plus propre.
Utiliser useState pour l’état local du composant :
S’assurer que useState est utilisé correctement pour gérer l’état local du composant
Vérifier si les variables d’état représentent les données minimales requises, en évitant les états inutiles ou redondants
Examiner les noms des variables d’état et de leurs setters pour s’assurer qu’ils décrivent clairement les données et les actions qu’ils représentent (par exemple, isModalOpen, setIsModalOpen)
Vérifier que la logique d’état complexe est abstraite dans des fonctions d’aide ou des rappels de mise à jour d’état (par exemple, setState(prevState => newState)), en évitant les re-rendus excessifs ou la manipulation directe de l’état
S’assurer que useEffect est utilisé de manière appropriée pour les effets secondaires tels que la récupération de données, les abonnements ou l’interaction avec des services externes
S’assurer qu’aucun effet secondaire n’est placé directement dans la logique de rendu
Examiner le tableau de dépendances de useEffect pour s’assurer qu’il reflète fidèlement les variables dont dépend l’effet (des dépendances incorrectes ou manquantes peuvent entraîner des boucles infinies ou un état obsolète)
Vérifier que les fonctions de nettoyage sont utilisées dans useEffect lorsque cela est nécessaire, en particulier pour les abonnements, les écouteurs d’événements ou les minuteurs, afin d’éviter les fuites de mémoire et les comportements indésirables
Éviter d’abuser de useEffect pour les états dérivés :
S’assurer que useEffect n’est pas utilisé à l’excès pour dériver des états qui peuvent être calculés directement dans le corps du composant ; par exemple, les données dérivées des props ou de l’état doivent être calculées dans la méthode de rendu ou à l’aide de la mémoïsation (useMemo), et non dans useEffect
Examiner les composants où l’état est défini dans useEffect et les refactoriser pour calculer les données dérivées en dehors de useEffect, sauf si la logique dépend de données asynchrones externes
// Correct: using useMemo for expensive computations
const ExpensiveComponent = ({ items }) => {
const computedValue = useMemo(() => {
console.log("Running expensive computation...");
return items.reduce((sum, item) => sum + item.value, 0);
}, [items]); // Only recalculates when `items` change
return
Computed Value: {computedValue}
;
};
// Wrong: using useEffect to set state
const ExpensiveComponent = ({ items }) => {
const [computedValue, setComputedValue] = useState(0);
useEffect(() => {
console.log("Running expensive computation...");
setComputedValue(items.reduce((sum, item) => sum + item.value, 0));
}, [items]); // Unnecessary effect
return
Computed Value: {computedValue}
;
};
**Utilisez useContext pour le partage d’état global :**
Assurez-vous que useContext est utilisé pour partager l’état global ou l’état de toute l’application, réduisant ainsi la nécessité de prop drilling à travers plusieurs composants.
Vérifiez le fournisseur de contexte et assurez-vous qu’il est utilisé à un niveau approprié dans l’arborescence des composants pour éviter les rendus inutiles des composants enfants.
Vérifiez que le contexte est utilisé avec parcimonie pour les données véritablement globales (par ex. authentification, thème) et que l’état local est géré au sein des composants à l’aide de useState ou d’autres hooks.
**Exploitez useReducer pour la logique d’état complexe :**
Assurez-vous que useReducer est utilisé pour gérer une logique d’état complexe, en particulier lorsque les transitions d’état impliquent plusieurs actions ou nécessitent des mises à jour structurées.
Vérifiez la fonction réductrice pour vous assurer qu’elle est pure, c’est-à-dire qu’elle dépend uniquement de ses entrées et ne provoque aucun effet secondaire ni ne modifie l’état directement.
Vérifiez que les types d’actions et les charges utiles sont clairement définis et descriptifs, garantissant que la logique réductrice reste claire et compréhensible.
**Utilisez useRef pour les valeurs mutables et la manipulation du DOM :**
Assurez-vous que useRef est utilisé pour les valeurs qui doivent persister entre les rendus sans déclencher de nouveaux rendus (par ex. éléments DOM, timers ou variables mutables).
Vérifiez l’utilisation de useRef pour la manipulation du DOM ou l’interaction avec des bibliothèques tierces.
Assurez-vous que la manipulation directe du DOM est réduite au minimum et que le modèle de rendu de React est respecté.
Vérifiez que useRef n’est pas mal utilisé pour la gestion de l’état : il ne doit être utilisé que dans les cas où les modifications de la référence ne nécessitent pas de déclencher de nouveaux rendus.
**Gérez l’état asynchrone avec une gestion d’erreurs appropriée :**
Assurez-vous que les opérations asynchrones (par ex. appels d’API, récupération de données) à l’intérieur de useEffect ou d’autres hooks sont gérées avec une gestion d’erreurs appropriée ; utilisez des blocs try-catch ou .catch() pour les promesses afin d’éviter les erreurs non interceptées.
Vérifiez que les variables d’état pour les états de chargement, de succès ou d’erreur (par ex. isLoading, isError) sont utilisées de manière cohérente lors de la gestion de l’état asynchrone, améliorant ainsi l’expérience utilisateur pendant les opérations asynchrones.
Vérifiez que les opérations asynchrones sont annulées lorsque le composant est démonté afin d’éviter de définir l’état sur des composants démontés, ce qui peut entraîner des fuites de mémoire ou des erreurs.
**Organisez l’état global avec Context ou des bibliothèques de gestion d’état :**
Assurez-vous que l’état global (par ex. authentification, préférences utilisateur ou paramètres de thème) est géré à l’aide de l’API React Context ou de bibliothèques de gestion d’état telles que Redux, Zustand ou Recoil.
Vérifiez l’utilisation des bibliothèques externes de gestion d’état pour vous assurer qu’elles sont nécessaires (pour les applications plus simples, React Context et useReducer peuvent suffire sans introduire de complexité inutile).
Vérifiez que la solution de gestion d’état globale est configurée avec des actions, des réducteurs ou des sélecteurs clairs pour minimiser le code répétitif et garantir que la logique d’état est maintenable.
**Évitez les pièges courants avec les React Hooks :**
Assurez-vous que les hooks sont appelés dans le bon ordre et uniquement à l’intérieur des composants fonctionnels ou des hooks personnalisés.
Assurez-vous que les hooks React ne sont pas appelés dans des boucles, des conditions ou des fonctions imbriquées.
Vérifiez les hooks personnalisés pour vous assurer qu’ils suivent les meilleures pratiques et encapsulent efficacement la logique réutilisable.
Vérifiez que les hooks personnalisés retournent des valeurs et des fonctions qui favorisent un comportement cohérent dans toute l’application.
Vérifiez que les hooks ne sont pas surexploités pour gérer un état local simple ou une logique qui peut être gérée dans le corps du composant.
Vérifiez si l’utilisation des hooks est simple et nécessaire.
Gestion des erreurs et cas limites
Une liste de contrôle React serait incomplète sans un examen approfondi de la gestion des erreurs et de la gestion des cas limites. Ceux-ci sont essentiels pour créer des applications React robustes capables de gérer gracieusement les défaillances inattendues et les cas limites.
Implémenter des limites d’erreurs pour une gestion d’erreurs élégante :
Assurez-vous que les limites d’erreurs sont implémentées aux points appropriés de l’arborescence des composants pour intercepter les erreurs JavaScript dans l’interface utilisateur et empêcher l’application entière de planter ; utilisez componentDidCatch ou créez des composants de limites d’erreurs avec React.ErrorBoundary
Revoyez le placement des limites d’erreurs pour vous assurer qu’elles couvrent les sections critiques de l’interface utilisateur (par exemple, autour des composants grands ou complexes) mais ne sont pas surutilisées, car cela pourrait masquer des problèmes plus profonds dans la base de code
Vérifiez que les limites d’erreurs affichent une interface utilisateur de repli significative (par exemple, des messages d’erreur, des options de nouvelle tentative) pour informer l’utilisateur du problème sans révéler de détails techniques
Gérer gracieusement les erreurs d’API et de récupération de données :
Assurez-vous que les erreurs provenant des appels d’API ou des opérations de récupération de données sont correctement gérées à l’aide de blocs try-catch ou de .catch() pour les promesses
Assurez-vous qu’il n’y a plus de rejets de promesses non résolus ou non gérés, car cela peut entraîner des erreurs d’exécution
Revoyez la manière dont les états d’erreur (par exemple, pannes réseau, erreurs d’API) sont communiqués aux utilisateurs
Assurez-vous que des messages d’erreur conviviaux sont affichés plutôt que des détails d’erreur techniques
Vérifiez que les états d’erreur sont gérés à l’aide de variables d’état appropriées (par exemple, isError, errorMessage) et assurez-vous que l’interface utilisateur propose des options de repli ou de nouvelle tentative en cas d’échec de la récupération des données
Anticiper et gérer les cas limites :
Assurez-vous que l’application anticipe et gère les cas limites courants, tels que les ensembles de données vides, les valeurs nulles ou indéfinies, ou les entrées utilisateur dépassant les limites attendues
Revoyez le rendu des listes de composants pour vous assurer qu’ils gèrent les scénarios où le tableau de données est vide ou contient des éléments invalides ; fournissez une interface utilisateur de repli (par exemple, « Aucun élément disponible ») pour ces cas
Vérifiez que les composants de formulaire gèrent les cas limites tels que les valeurs d’entrée excessivement longues, les formats invalides ou les entrées utilisateur inattendues ; utilisez une logique de validation pour empêcher la soumission de données invalides
Assurer la gestion des erreurs pour les opérations asynchrones :
Assurez-vous que les opérations asynchrones, telles que la récupération de données avec fetch, axios, ou GraphQL, sont encapsulées dans des mécanismes de gestion d’erreurs (par exemple, try-catch ou .catch() pour les promesses) afin d’éviter les échecs silencieux
Revoyez la gestion des états de chargement, de succès et d’erreur pour les opérations asynchrones. Assurez-vous que le feedback approprié est donné aux utilisateurs (par exemple, indicateurs de chargement, messages d’erreur, confirmations de succès)
Vérifiez que les opérations de longue durée ou les requêtes réseau sont gérées gracieusement, avec une gestion d’erreurs et une logique de nouvelle tentative appropriées pour améliorer l’expérience utilisateur en cas de problèmes réseau
Valider et assainir les entrées utilisateur :
Assurez-vous que les entrées utilisateur sont correctement validées côté client et côté serveur pour éviter que des données invalides ou inattendues ne causent des problèmes. Utilisez des bibliothèques de validation (par exemple, Yup, Formik) ou une logique de validation personnalisée pour les formulaires complexes
Revoyez la logique de validation des entrées pour vous assurer qu’elle couvre les cas limites courants tels que les chaînes vides, les caractères spéciaux et les entrées excessivement longues ; fournissez des messages de validation utiles pour guider les utilisateurs
Vérifiez que les entrées utilisateur sont assainies pour prévenir les problèmes de sécurité potentiels, tels que l’injection de scripts malveillants ou de caractères invalides dans les formulaires
Gérer les valeurs par défaut et de repli pour les données manquantes :
Assurez-vous que des valeurs par défaut sont fournies lors de l’accès à des données potentiellement manquantes ou indéfinies, en particulier lors du traitement des réponses d’API ou des props optionnels
Revoyez l’utilisation de la chaîne d’opérateurs optionnels (?.) et des valeurs de paramètres par défaut (||) pour gérer gracieusement les valeurs indéfinies ou nulles
Vérifiez que les composants affichent un contenu de repli approprié lorsque les données sont manquantes ou incomplètes, en évitant les écrans vides ou les erreurs d’interface utilisateur
Afficher des messages d’erreur significatifs et conviviaux :
Assurez-vous que les messages d’erreur affichés aux utilisateurs sont clairs, concis et utiles
Assurez-vous qu’aucun message d’erreur brut provenant des réponses d’API ou du serveur n’est affiché, car ils peuvent contenir du jargon technique
Revoyez les messages d’erreur dans toute l’application pour assurer la cohérence du ton et du style, en veillant à ce qu’ils guident les utilisateurs à prendre des mesures correctives (par exemple, « Veuillez réessayer » ou « Contactez le support pour obtenir de l’aide »)
Vérifiez que les erreurs critiques (par exemple, échecs de récupération de données, erreurs de soumission de formulaire) incluent des options exploitables, telles que des boutons de nouvelle tentative ou des liens vers des pages de support
Implémenter des cas limites pour les props et l’état des composants
Assurez-vous que les composants gèrent gracieusement les valeurs de props inattendues ou incorrectes
Vérifiez si PropTypes ou TypeScript sont utilisés pour appliquer les types et la structure attendus des props passés aux composants
Revoyez les composants pour vous assurer qu’ils gèrent les cas limites tels que les props manquantes ou incomplètes
Utilisez des props par défaut ou fournissez une logique conditionnelle pour gérer ces cas sans casser le composant
Vérifiez que les composants se rendent correctement lorsqu’ils sont fournis avec divers cas limites dans l’état, tels que des tableaux vides, des valeurs nulles ou des états par défaut
Utiliser des techniques de programmation défensive :
Assurez-vous que les techniques de programmation défensive sont utilisées pour prévenir les erreurs d’exécution causées par des entrées inattendues, des références nulles ou des données invalides (par exemple, vérifiez les valeurs nulles ou indéfinies avant d’effectuer des opérations dessus)
Revoyez la logique conditionnelle pour vous assurer qu’elle gère tous les cas limites possibles, empêchant l’application d’entrer dans un état instable lorsqu’elle est fournie avec des données ou des entrées inattendues
Vérifiez que les composants sont testés pour leur robustesse, en gérant divers cas limites pendant les phases de développement et de test pour éviter les plantages inattendus ou les exceptions non gérées en production
Éviter les échecs silencieux et enregistrer efficacement les erreurs :
Assurez-vous que les erreurs sont enregistrées efficacement dans les environnements de développement et de production
Assurez-vous que des outils de journalisation (par exemple, Sentry, LogRocket) sont utilisés pour capturer des informations d’erreur détaillées sans les exposer à l’utilisateur final
Revoyez le code pour détecter les échecs silencieux potentiels, où des erreurs se produisent mais ne sont ni enregistrées ni communiquées à l’utilisateur
Assurez-vous que les erreurs sont interceptées et gérées de manière appropriée, avec une logique de repli ou des messages d’erreur
Vérifiez que les journaux d’erreurs sont structurés et incluent des informations pertinentes (par exemple, nom du composant, trace de la pile, action de l’utilisateur) pour faciliter le débogage à l’avenir
Utiliser des limites d’erreurs appropriées pour les composants tiers
Assurez-vous que des limites d’erreurs sont appliquées autour des composants ou des bibliothèques tiers qui peuvent générer des erreurs inattendues, en particulier lors de l’intégration avec du code complexe ou inconnu
Revoyez la manière dont les bibliothèques tierces gèrent les erreurs et assurez-vous que toute défaillance est capturée au sein de l’application
Lors de la gestion des erreurs en interne, assurez-vous que les bibliothèques externes ne sont pas la seule dépendance
Optimisation des performances
React est incroyablement populaire, avec 39,5 % des développeurs logiciels dans le monde qui le choisissent comme framework web de prédilection (juste après Node.js). Cependant, à mesure que votre application gagne en complexité, vous pourriez constater une baisse de ses performances, ce qui peut impacter significativement la satisfaction des utilisateurs. C’est pourquoi les performances de React sont cruciales pour offrir une expérience utilisateur fluide.
Nos efforts d’optimisation des performances de React peuvent se concentrer sur des domaines clés tels que la réduction des ré-rendus de composants inutiles, la minimisation de la taille des bundles JavaScript et l’amélioration spectaculaire des temps de chargement. Lors d’une revue de code, nous partageons des techniques d’optimisation des performances de React exploitables, en identifiant précisément les goulots d’étranglement et les inefficacités qui pourraient freiner la réactivité et l’évolutivité de votre application.
Utilisez React.memo pour la mémorisation des composants :
Assurez-vous que les composants qui n’ont pas besoin d’être ré-rendus fréquemment sont encapsulés dans React.memo pour éviter les ré-rendus inutiles.
Examinez les composants recevant les mêmes props de manière répétée pour vérifier si React.memo peut être appliqué, réduisant ainsi le nombre de rendus et améliorant les performances dans les grands arbres de composants.
Vérifiez que React.memo est utilisé sélectivement pour les composants où les ré-rendus sont coûteux.
Assurez-vous que React.memo n’est pas surutilisé sur des composants simples ou légers où l’optimisation pourrait ne pas être nécessaire.
Utilisez useMemo et useCallback pour les calculs et les fonctions coûteux :
Assurez-vous que useMemo est utilisé pour mémoriser les calculs coûteux ou les données dérivées, évitant ainsi les recalculs inutiles à chaque rendu.
Examinez l’utilisation de useCallback pour mémoriser les fonctions de rappel passées aux composants enfants, évitant la recréation inutile de fonctions qui pourrait entraîner des ré-rendus non nécessaires des composants enfants.
Vérifiez que les tableaux de dépendances pour useMemo et useCallback sont corrects et couvrent toutes les variables susceptibles de déclencher un recalcul.
Évitez les ré-rendus inutiles :
Assurez-vous que les ré-rendus de composants sont minimisés en vérifiant si les valeurs des props ou de l’état ont changé avant de mettre à jour le composant.
Utilisez une logique de comparaison appropriée dans la méthode de cycle de vie shouldComponentUpdate (pour les composants de classe) ou en utilisant des hooks comme React.memo et useCallback dans les composants fonctionnels.
Examinez les composants pour les mises à jour d’état ou de props inutiles qui peuvent déclencher des ré-rendus.
Assurez-vous que seules les données pertinentes sont passées en tant que props et qu’il n’y a pas de mise à jour de l’état avec les mêmes valeurs.
Vérifiez que des props inutiles (tels que des props non utilisés ou par défaut) ne sont pas passés aux composants enfants, réduisant ainsi le risque de ré-rendus involontaires.
Implémentez le chargement différé pour la séparation du code :
Assurez-vous que la séparation du code est implémentée à l’aide de React.lazy et Suspense pour charger les composants à la demande, réduisant la taille initiale du bundle et améliorant les temps de chargement pour les utilisateurs.
Examinez les routes et les grands composants pour vérifier qu’ils sont chargés de manière différée, en particulier pour les composants qui ne sont pas nécessaires immédiatement au chargement de la page (par exemple, les composants pour les routes ou les modales).
Vérifiez que des composants de secours Suspense sont utilisés pour afficher des états de chargement pendant que les composants chargés de manière différée sont récupérés ; assurez-vous que l’interface utilisateur de secours est claire et conviviale.
Optimisez les listes avec React.Fragment et les props key :
Assurez-vous que les listes rendues à l’aide de .map() incluent une prop key unique pour chaque élément afin d’aider React à optimiser le processus de réconciliation et à éviter les ré-rendus inutiles.
Vérifiez que React.Fragment est utilisé lorsque nécessaire pour regrouper des éléments frères sans ajouter de nœuds supplémentaires au DOM, en particulier dans les listes ou les rendus conditionnels.
Vérifiez que le rendu des listes est efficace, en évitant les calculs ou les ré-rendus inutiles lorsque les données de la liste n’ont pas changé.
Implémentez le défilement infini ou la pagination pour les grands ensembles de données :
Assurez-vous que les grands ensembles de données sont gérés efficacement en implémentant la pagination ou le défilement infini au lieu de charger toutes les données d’un coup.
Vérifiez que la pagination ou le défilement infini est utilisé pour les listes ou les tableaux qui affichent de grandes quantités de données, en garantissant que seul un nombre limité d’éléments est rendu à la fois.
Vérifiez que des techniques de chargement différé ou de défilement virtuel sont appliquées le cas échéant pour minimiser le nombre d’éléments DOM rendus simultanément.
Utilisez CSS-in-JS ou la séparation du code pour les styles :
Assurez-vous que les styles sont optimisés à l’aide de solutions CSS-in-JS comme Styled Components ou Emotion, ou en séparant les fichiers CSS pour réduire la taille des styles chargés initialement.
Vérifiez que les CSS critiques sont chargés initialement, tandis que les styles non essentiels sont différés jusqu’à ce qu’ils soient nécessaires.
Vérifiez que le style dynamique est géré efficacement, en évitant les styles en ligne ou le recalcul des styles à chaque rendu, sauf si nécessaire.
Minimisez la taille du bundle JavaScript :
Assurez-vous que les bibliothèques inutiles ou non utilisées sont supprimées du projet pour minimiser la taille du bundle JavaScript.
Utilisez des outils comme Webpack ou Parcel pour analyser et “tree-shaker” le code inutilisé.
Examinez le projet pour les grandes dépendances qui peuvent être remplacées par des alternatives plus légères ou des implémentations personnalisées afin de réduire la taille globale du bundle.
Vérifiez que les assets (par exemple, images, polices) sont optimisés et que les grandes bibliothèques sont divisées en plus petits morceaux à l’aide d’importations dynamiques pour la séparation du code.
Utilisez useRef pour éviter les ré-rendus pour les données mutables :
Assurez-vous que useRef est utilisé pour les données mutables qui n’ont pas besoin de déclencher de ré-rendus, tels que les références DOM, les minuteries ou les interactions avec des API externes.
Examinez l’utilisation de useRef pour stocker des valeurs qui persistent entre les rendus sans provoquer de ré-rendu du composant, tels que les éléments de formulaire ou les valeurs d’animation.
Vérifiez que useRef n’est pas utilisé pour gérer l’état qui devrait déclencher des mises à jour de l’interface utilisateur, car cela pourrait entraîner des incohérences entre l’interface utilisateur et l’état de l’application.
Optimisez les performances dans les formulaires et la gestion des entrées :
Assurez-vous que les entrées de formulaire sont optimisées en utilisant des gestionnaires onChange qui ne mettent à jour l’état que lorsque nécessaire.
Assurez-vous qu’il n’y a pas de ré-rendu du formulaire entier à chaque pression de touche ou interaction.
Examinez les composants de formulaire pour vous assurer que les composants contrôlés ne se ré-rendent pas ou ne déclenchent pas de mises à jour inutilement ; utilisez des techniques telles que le “debouncing” ou useCallback pour optimiser la gestion des entrées.
Vérifiez que les validations de formulaire sont optimisées en utilisant des bibliothèques comme Formik ou React Hook Form, qui gèrent l’état du formulaire efficacement et évitent les ré-rendus.
Implémentez Suspense pour la récupération de données :
Assurez-vous que Suspense est utilisé pour la récupération de données en combinaison avec le Mode Concurrent de React pour permettre de meilleures performances de rendu en différant ou en suspendant le rendu des composants jusqu’à ce que les données soient disponibles.
Examinez l’utilisation de bibliothèques de récupération de données (par exemple, SWR, React Query) qui sont optimisées pour React et prennent en charge la mise en cache, la revalidation et la récupération en arrière-plan, minimisant ainsi le besoin de requêtes de données redondantes.
Vérifiez que les états de chargement sont gérés efficacement avec Suspense ou une logique personnalisée, en garantissant que l’interface utilisateur reste réactive pendant l’attente des données.
Optimisez les images et les médias :
Assurez-vous que les images et les fichiers multimédias sont optimisés pour les performances à l’aide de techniques telles que le chargement différé (loading=”lazy” pour les images), les tailles d’images responsives et les formats WebP pour réduire la taille des fichiers et le temps de chargement.
Vérifiez que les fichiers multimédias volumineux (par exemple, vidéos) sont différés ou chargés à la demande, réduisant ainsi la charge de chargement initiale pour les utilisateurs disposant de connexions lentes.
Vérifiez que des outils tels que la compression d’images ou les réseaux de diffusion de contenu (CDN) sont utilisés pour servir des assets optimisés, améliorant les temps de chargement et réduisant l’utilisation de la bande passante.
Profilez et mesurez les performances
Assurez-vous que les outils de profilage de performance (par exemple, React Profiler, Chrome DevTools) sont utilisés pour identifier les goulots d’étranglement, mesurer les temps de rendu des composants et optimiser les zones lentes de l’application.
Examinez les benchmarks de performance pour identifier quels composants ou parties de l’application causent des ralentissements, en particulier lors des interactions utilisateur ou des cycles de rendu complexes.
Vérifiez que les techniques d’optimisation (par exemple, mémorisation, chargement différé) sont appliquées sur la base de données de performance réelles plutôt que d’une optimisation prématurée, garantissant des gains de performance significatifs.
Bonnes pratiques de sécurité
La sécurité de React est non négociable. Vos applications React traitent des données utilisateur sensibles, interagissent avec diverses API et fonctionnent finalement dans l’environnement potentiellement non sécurisé du navigateur d’un utilisateur. Cela rend absolument crucial de garantir la mise en œuvre correcte des meilleures pratiques de sécurité React. En procédant ainsi, vous protégez à la fois votre application et ses utilisateurs contre une série de vulnérabilités telles que le scripting intersite (XSS), les fuites de données insidieuses et de nombreuses autres cyberattaques courantes.
Lorsque nous effectuons un examen de code, notre analyse approfondie de la sécurité React JS garantit que votre application est non seulement résiliente face aux menaces, mais aussi qu’elle gère toutes les données sensibles avec le plus grand soin et la plus grande sécurité.
Assainir les entrées utilisateur pour prévenir les attaques XSS :
Assurez-vous que toutes les entrées utilisateur sont assainies avant d’être rendues dans l’interface utilisateur
Vérifiez si des bibliothèques comme DOMPurify sont utilisées pour supprimer le contenu potentiellement nuisible, en particulier lors du rendu de HTML ou de contenu généré par l’utilisateur
Examinez les composants pour vous assurer que les méthodes dangereuses comme dangerouslySetInnerHTML sont évitées, sauf nécessité absolue (si elles sont utilisées, vérifiez que le contenu est correctement assaini pour prévenir les attaques XSS)
Vérifiez que les bibliothèques tierces gérant les données utilisateur (par exemple, les éditeurs de texte enrichi, les bibliothèques de formulaires) assainissent correctement le contenu avant le rendu
Implémenter une authentification et une autorisation sécurisées :
Assurez-vous que les mécanismes d’authentification sont sécurisés, en tirant parti de normes comme OAuth2 ou des jetons Web JSON (JWT) pour gérer l’authentification des utilisateurs
Vérifiez si les jetons sont stockés en toute sécurité à l’aide de cookies HTTP-only pour empêcher l’accès côté client
Examinez les mécanismes de contrôle d’accès pour vérifier que les composants et les routes sont protégés en fonction du statut d’authentification et d’autorisation de l’utilisateur
Vérifiez si PrivateRoute ou des techniques équivalentes sont utilisées pour sécuriser les routes protégées
Vérifiez que les informations sensibles comme les jetons JWT, les clés d’API ou les identifiants utilisateur ne sont jamais stockées dans le stockage local, le stockage de session, ou directement dans le code JavaScript
Se prémunir contre le Cross-Site Request Forgery (CSRF) :
Assurez-vous que la protection CSRF est mise en œuvre, en particulier pour les opérations modifiant l’état (par exemple, soumissions de formulaires, requêtes API)
Vérifiez si des jetons anti-CSRF qui sont validés côté serveur sont utilisés
Examinez tout composant de gestion de formulaires ou d’interaction avec des API pour vous assurer qu’ils utilisent des en-têtes et des jetons sécurisés (par exemple, X-CSRF-Token) pour se protéger contre les attaques CSRF
Vérifiez que les requêtes modifiant des données sensibles nécessitent des jetons CSRF valides, garantissant que les requêtes non autorisées ne peuvent pas être traitées
Utiliser HTTPS et les cookies sécurisés :
Assurez-vous que toute communication entre le client et le serveur est chiffrée à l’aide de HTTPS. Évitez de transmettre des informations sensibles (par exemple, jetons d’authentification, clés d’API) via des connexions HTTP non sécurisées
Examinez les paramètres des cookies pour vous assurer que des cookies sécurisés et HTTP-only sont utilisés pour stocker les jetons d’authentification et les informations de session, empêchant l’accès via JavaScript
Vérifiez que l’attribut SameSite est défini sur les cookies pour empêcher l’accès aux cookies inter-sites et réduire le risque d’attaques CSRF
Prévenir l’exposition de données sensibles :
Assurez-vous que les données sensibles (par exemple, mots de passe, numéros de carte de crédit) ne sont jamais enregistrées ou exposées dans les outils de développement du navigateur
Vérifiez qu’il n’y a pas de journalisation d’informations sensibles dans la console ou leur envoi dans des messages d’erreur
Examinez les requêtes et les réponses API pour vous assurer qu’aucune donnée sensible n’est renvoyée dans les réponses
Vérifiez que des données telles que les mots de passe utilisateur, les jetons ou les informations personnellement identifiables (PII) ne sont jamais envoyées au client
Vérifiez que le stockage côté client (par exemple, stockage local, stockage de session) ne contient pas d’informations sensibles comme des jetons JWT ou des identifiants utilisateur
Implémenter une politique de sécurité de contenu (CSP) :
Assurez-vous qu’une politique de sécurité de contenu (CSP) est mise en œuvre pour empêcher l’exécution de scripts ou de ressources non autorisés (cela permet d’atténuer les attaques XSS et d’injection de données en restreignant le contenu qui peut être chargé sur une page)
Examinez la configuration de la CSP pour vous assurer que seules des sources fiables (par exemple, self, CDN approuvés) sont autorisées pour le chargement de scripts, de styles et d’autres actifs
Assurez-vous qu’il n’y a pas d’utilisation des directives unsafe-inline ou unsafe-eval
Vérifiez que tous les scripts ou styles en ligne nécessaires sont minimisés et correctement gérés par la CSP, garantissant qu’ils n’introduisent pas de vulnérabilités de sécurité
Prévenir les attaques par détournement de clic (Clickjacking) :
Assurez-vous que l’en-tête X-Frame-Options est défini sur DENY ou SAMEORIGIN pour empêcher l’application d’être intégrée dans des iframes sur d’autres sites
Examinez toute utilisation légitime d’iframes (par exemple, intégration de contenu tiers) pour vous assurer que les risques de sécurité sont atténués et que les iframes sont utilisés en toute sécurité
Vérifiez que tout contenu intégré, en particulier celui provenant de sources tierces, est fiable et correctement sécurisé
Valider les données provenant des API et des sources externes :
Assurez-vous que les données récupérées des API ou des sources externes sont correctement validées avant d’être traitées ou rendues dans l’interface utilisateur
Examinez les appels d’API et vérifiez que la validation côté client est complétée par une validation côté serveur, garantissant que les données fournies par l’utilisateur sont assainies et validées sur le serveur
Vérifiez que les données entrantes sont vérifiées pour leur intégrité et leur structure (par exemple, validation de schémas JSON), empêchant l’utilisation de données malformées ou malveillantes dans l’application
Utiliser la limitation du débit et le throttling pour les requêtes API :
Assurez-vous que des mécanismes de limitation du débit et de throttling sont en place pour prévenir l’abus des API, tels que les attaques par force brute ou les attaques par déni de service (DoS)
Vérifiez si ces protections sont implémentées côté serveur pour limiter le nombre de requêtes qu’un client peut effectuer dans un laps de temps spécifié
Examinez l’interaction de l’application avec les API pour vous assurer que le throttling des requêtes ou les limites de débit sont respectés
Vérifiez qu’il n’y a pas d’appels API fréquents et inutiles qui pourraient entraîner une surutilisation des ressources
Vérifiez que les API externes consommées disposent de protections adéquates de limitation du débit, et que la gestion des erreurs pour les réponses limitées en débit est implémentée
Utiliser une gestion appropriée des erreurs sans exposer d’informations internes
Assurez-vous que les messages d’erreur présentés aux utilisateurs sont génériques et ne révèlent pas d’informations internes telles que des traces de pile, des chemins de serveur ou des détails de base de données
Examinez la gestion des erreurs dans toute l’application pour vous assurer que les erreurs internes sont enregistrées côté serveur mais ne sont pas exposées au client
Vérifiez que les informations sensibles sont supprimées des réponses d’erreur avant qu’elles ne soient envoyées au client, garantissant que les attaquants potentiels ne peuvent pas collecter de détails sur le système
Surveiller et journaliser les événements liés à la sécurité
Assurez-vous que les événements de sécurité importants, tels que les tentatives de connexion échouées, les tentatives d’accès non autorisées et les violations de données, sont enregistrés pour une analyse et une réponse futures
Vérifiez si un outil de journalisation comme Sentry ou LogRocket est utilisé pour capturer et signaler les incidents liés à la sécurité
Examinez les configurations de journalisation pour vous assurer que les journaux de sécurité sont stockés en toute sécurité et accessibles uniquement par du personnel autorisé
Vérifiez qu’il n’y a pas de journalisation de données sensibles en texte brut
Vérifiez que des systèmes de journalisation et de surveillance sont en place pour détecter et répondre aux menaces de sécurité potentielles en temps réel
Améliorez la qualité de votre application React avec Redwerk
Chez Redwerk, nous avons livré avec succès plus de 250 projets à des entreprises en Amérique du Nord, en Europe, en Afrique, en Australie et en Nouvelle-Zélande. Nous accompagnons nos clients à chaque étape du cycle de développement logiciel, les aidant à se débarrasser de la dette technique, à adopter des pratiques de codage saines et à mettre en œuvre des flux de travail éprouvés qui augmentent la fréquence et la fiabilité des versions logicielles. Voici quelques projets React JS qui ont bénéficié de notre expertise.
Accélération de la livraison de fonctionnalités pour Orderstep
Client :Orderstep, un fournisseur danois de SaaS de gestion de devis.
Contraintes : Une petite équipe interne aux prises avec des demandes de fonctionnalités en retard de la part des utilisateurs premium.
Solution : Redwerk est intervenue pour aider à livrer à temps des fonctionnalités promises depuis longtemps aux utilisateurs. Le backend de la boutique en ligne étant déjà complet, rendre un framework traditionnel compatible avec le frontend aurait nécessité des ajustements importants. Pour combiner les avantages d’une Single Page Application (SPA) avec leur configuration existante, nous avons stratégiquement intégré React pour les parties interactives de la boutique en ligne, laissant les pages statiques indépendantes du framework.
Résultat : Le développement en temps voulu de la fonctionnalité de la boutique en ligne pour les utilisateurs premium a considérablement augmenté les revenus d’abonnement.
Mise à niveau rapide de modules pour Cakemail
Client :Cakemail, une scale-up canadienne spécialisée dans les outils de marketing par e-mail.
Contraintes : Un délai serré et un besoin urgent de mettre à niveau un module d’application critique.
Solution : Nous avons préparé entièrement le frontend de la section Formulaires pour une intégration transparente dans la nouvelle version de l’application Cakemail. Notre assistance a permis à Cakemail de réaliser la transition de Cakemail v4 à Cakemail v5 sans compromettre la fonctionnalité de l’application.
Résultat : Le module de formulaire d’abonnement a été refactorisé avec succès en moins de 90 jours, permettant à Cakemail de déployer sa version d’application mise à niveau comme prévu.
Réarchitecture et lancement de plateforme pour Evolv
Client :Evolv, une plateforme d’optimisation d’expérience axée sur l’IA basée aux États-Unis.
Contraintes : Pression pour livrer de nouvelles fonctionnalités pour la croissance de la base d’utilisateurs, combinée à un travail de réarchitecture approfondi nécessaire après une scission de Sentient Technologies, ce qui a surchargé l’équipe interne.
Solution : Redwerk a été engagée pour développer le produit principal d’Evolv : une plateforme d’optimisation pionnière comprenant un éditeur Web et un gestionnaire. L’éditeur Web est l’application de bureau d’Evolv qui permet de coder des améliorations de l’UX sans accès direct au code source du client, ainsi que de prévisualiser, modifier et tester les changements implémentés. Le gestionnaire est la plateforme Web d’Evolv, proposant des paramètres de test avancés pour lancer des expériences. Nous avons également continué à maintenir la plateforme.
Résultat : Transformation de l’offre héritée, Sentient Ascend, en la solution de croissance numérique n°1 pilotée par l’IA. En collaboration avec l’équipe de livraison Redwerk, Evolv a lancé avec succès son nouveau produit — Evolv 1.0, qui est maintenant utilisé par de nombreux clients Evolv.
Que vous cherchiez à embaucher des développeurs React JS pour compléter votre équipe interne ou que vous ayez besoin d’une assistance experte pour une revue impartiale du code React, nous serions ravis de vous aider. Contactez-nous dès aujourd’hui pour nous faire part de vos besoins et obtenir une compréhension claire de la manière dont ils peuvent être satisfaits, y compris une estimation gratuite du projet.
Découvrez comment nous avons aidé Evolv à réarchitecturer sa plateforme pilotée par l'IA construite avec React JS
Responsable de l'équipe de développement chez Redwerk
Diplômé en systèmes de contrôle et en génie informatique, Dmitry excelle dans la création d'architectures logicielles robustes. Fort de plus de 20 ans d'expérience technique, il allie un esprit analytique aiguisé à d'excellentes aptitudes à la communication. Plus par auteur