Directives de Développement Frontend
Objectif
Guide complet pour le développement React moderne, mettant l'accent sur la récupération de données basée sur Suspense, le chargement différé, une organisation appropriée des fichiers et l'optimisation des performances.
Quand Utiliser Cette Compétence
- Créer de nouveaux composants ou pages
- Construire de nouvelles fonctionnalités
- Récupérer des données avec TanStack Query
- Configurer le routage avec TanStack Router
- Styliser des composants avec MUI v7
- Optimiser les performances
- Organiser le code frontend
- Bonnes pratiques TypeScript
Démarrage Rapide
Checklist pour Nouveau Composant
Vous créez un composant ? Suivez cette checklist :
- Utiliser le modèle
React.FC<Props>avec TypeScript - Chargement différé si composant lourd :
React.lazy(() => import()) - Envelopper dans
<SuspenseLoader>pour les états de chargement - Utiliser
useSuspenseQuerypour la récupération de données - Alias d'import :
@/,~types,~components,~features - Styles : En ligne si <100 lignes, fichier séparé si >100 lignes
- Utiliser
useCallbackpour les gestionnaires d'événements passés aux enfants - Export par défaut en bas
- Pas de retours anticipés avec des spinners de chargement
- Utiliser
useMuiSnackbarpour les notifications utilisateur
Checklist pour Nouvelle Fonctionnalité
Création d'une fonctionnalité ? Mettez en place cette structure :
- Créer le répertoire
features/{nom-fonctionnalite}/ - Créer les sous-répertoires :
api/,components/,hooks/,helpers/,types/ - Créer le fichier de service API :
api/{fonctionnalite}Api.ts - Configurer les types TypeScript dans
types/ - Créer la route dans
routes/{nom-fonctionnalite}/index.tsx - Chargement différé des composants de la fonctionnalité
- Utiliser les limites Suspense
- Exporter l'API publique depuis le
index.tsde la fonctionnalité
Référence Rapide des Alias d'Import
| Alias | Résout vers | Exemple |
|---|---|---|
@/ | src/ | import { apiClient } from '@/lib/apiClient' |
~types | src/types | import type { User } from '~types/user' |
~components | src/components | import { SuspenseLoader } from '~components/SuspenseLoader' |
~features | src/features | import { authApi } from '~features/auth' |
Défini dans : vite.config.ts lignes 180-185
Aide-Mémoire des Imports Courants
// React & Chargement Différé
import React, { useState, useCallback, useMemo } from 'react';
const Heavy = React.lazy(() => import('./Heavy'));
// Composants MUI
import { Box, Paper, Typography, Button, Grid } from '@mui/material';
import type { SxProps, Theme } from '@mui/material';
// TanStack Query (Suspense)
import { useSuspenseQuery, useQueryClient } from '@tanstack/react-query';
// TanStack Router
import { createFileRoute } from '@tanstack/react-router';
// Composants du Projet
import { SuspenseLoader } from '~components/SuspenseLoader';
// Hooks
import { useAuth } from '@/hooks/useAuth';
import { useMuiSnackbar } from '@/hooks/useMuiSnackbar';
// Types
import type { Post } from '~types/post';
Guides Thématiques
🎨 Modèles de Composants
Les composants React modernes utilisent :
React.FC<Props>pour la sécurité des typesReact.lazy()pour le fractionnement du codeSuspenseLoaderpour les états de chargement- Modèle const nommé + export par défaut
Concepts Clés :
- Chargement différé des composants lourds (DataGrid, graphiques, éditeurs)
- Toujours envelopper les composants différés dans Suspense
- Utiliser le composant SuspenseLoader (avec animation de fondu)
- Structure du composant : Props → Hooks → Gestionnaires → Rendu → Export
📖 Guide Complet : resources/component-patterns.md
📊 Récupération de Données
MODÈLE PRINCIPAL : useSuspenseQuery
- Utiliser avec les limites Suspense
- Stratégie cache-first (vérifier le cache grille avant l'API)
- Remplace les vérifications
isLoading - Type-safe avec les génériques
Couche de Service API :
- Créer
features/{feature}/api/{feature}Api.ts - Utiliser l'instance axios
apiClient - Méthodes centralisées par fonctionnalité
- Format de route :
/form/route(PAS/api/form/route)
📖 Guide Complet : resources/data-fetching.md
📁 Organisation des Fichiers
features/ vs components/ :
features/: Spécifique au domaine (posts, comments, auth)components/: Vraiment réutilisables (SuspenseLoader, CustomAppBar)
Sous-répertoires des Fonctionnalités :
features/
ma-fonctionnalite/
api/ # Couche de service API
components/ # Composants de la fonctionnalité
hooks/ # Hooks personnalisés
helpers/ # Fonctions utilitaires
types/ # Types TypeScript
📖 Guide Complet : resources/file-organization.md
🎨 Stylisation
En ligne vs Séparé :
- <100 lignes : En ligne
const styles: Record<string, SxProps<Theme>> -
100 lignes : Fichier
.styles.tsséparé
Méthode Principale :
- Utiliser la prop
sxpour les composants MUI - Type-safe avec
SxProps<Theme> - Accès au thème :
(theme) => theme.palette.primary.main
Grille MUI v7 :
<Grid size={{ xs: 12, md: 6 }}> // ✅ Syntaxe v7
<Grid xs={12} md={6}> // ❌ Ancienne syntaxe
📖 Guide Complet : resources/styling-guide.md
🛣️ Routage
TanStack Router - Basé sur les Dossiers :
- Répertoire :
routes/ma-route/index.tsx - Chargement différé des composants
- Utiliser
createFileRoute - Données de fil d'Ariane dans le loader
Exemple :
import { createFileRoute } from '@tanstack/react-router';
import { lazy } from 'react';
const MaPage = lazy(() => import('@/features/ma-fonctionnalite/components/MaPage'));
export const Route = createFileRoute('/ma-route/')({
component: MaPage,
loader: () => ({ crumb: 'Ma Route' }),
});
📖 Guide Complet : resources/routing-guide.md
⏳ États de Chargement et d'Erreur
RÈGLE CRITIQUE : Pas de Retours Anticipés
// ❌ JAMAIS - Provoque un décalage de mise en page
if (isLoading) {
return <LoadingSpinner />;
}
// ✅ TOUJOURS - Mise en page cohérente
<SuspenseLoader>
<Contenu />
</SuspenseLoader>
Pourquoi : Empêche le décalage cumulatif de mise en page (CLS), meilleure expérience utilisateur
Gestion des Erreurs :
- Utiliser
useMuiSnackbarpour les retours utilisateur - JAMAIS
react-toastify - Callbacks
onErrorde TanStack Query
📖 Guide Complet : resources/loading-and-error-states.md
⚡ Performance
Modèles d'Optimisation :
useMemo: Calculs coûteux (filtre, tri, map)useCallback: Gestionnaires d'événements passés aux enfantsReact.memo: Composants coûteux- Recherche avec debounce (300-500ms)
- Prévention des fuites mémoire (nettoyage dans useEffect)
📖 Guide Complet : resources/performance.md
📘 TypeScript
Normes :
- Mode strict, pas de type
any - Types de retour explicites sur les fonctions
- Imports de type :
import type { User } from '~types/user' - Interfaces de props des composants avec JSDoc
📖 Guide Complet : resources/typescript-standards.md
🔧 Modèles Courants
Sujets Couverts :
- React Hook Form avec validation Zod
- Contrats d'encapsulation DataGrid
- Normes des composants Dialog
- Hook
useAuthpour l'utilisateur courant - Modèles de mutation avec invalidation de cache
📖 Guide Complet : resources/common-patterns.md
📚 Exemples Complets
Exemples fonctionnels complets :
- Composant moderne avec tous les modèles
- Structure de fonctionnalité complète
- Couche de service API
- Route avec chargement différé
- Suspense + useSuspenseQuery
- Formulaire avec validation
📖 Guide Complet : resources/complete-examples.md
Guide de Navigation
| Besoin de... | Lisez cette ressource |
|---|---|
| Créer un composant | component-patterns.md |
| Récupérer des données | data-fetching.md |
| Organiser les fichiers/dossiers | file-organization.md |
| Styliser les composants | styling-guide.md |
| Configurer le routage | routing-guide.md |
| Gérer le chargement/erreurs | loading-and-error-states.md |
| Optimiser les performances | performance.md |
| Types TypeScript | typescript-standards.md |
| Formulaires/Auth/DataGrid | common-patterns.md |
| Voir des exemples complets | complete-examples.md |
Principes Fondamentaux
- Charger Différé Tout ce qui est Lourd : Routes, DataGrid, graphiques, éditeurs
- Suspense pour le Chargement : Utiliser SuspenseLoader, pas de retours anticipés
- useSuspenseQuery : Modèle principal de récupération de données pour le nouveau code
- Les Fonctionnalités sont Organisées : Sous-répertoires api/, components/, hooks/, helpers/
- Styles Basés sur la Taille : <100 en ligne, >100 séparé
- Alias d'Import : Utiliser @/, ~types, ~components, ~features
- Pas de Retours Anticipés : Empêche le décalage de mise en page
- useMuiSnackbar : Pour toutes les notifications utilisateur
Référence Rapide : Structure des Fichiers
src/
features/
ma-fonctionnalite/
api/
maFonctionnaliteApi.ts # Service API
components/
MaFonctionnalite.tsx # Composant principal
SousComposant.tsx # Composants liés
hooks/
useMaFonctionnalite.ts # Hooks personnalisés
useSuspenseMaFonctionnalite.ts # Hooks Suspense
helpers/
maFonctionnaliteHelpers.ts # Utilitaires
types/
index.ts # Types TypeScript
index.ts # Exports publics
components/
SuspenseLoader/
SuspenseLoader.tsx # Chargeur réutilisable
CustomAppBar/
CustomAppBar.tsx # Barre d'appli réutilisable
routes/
ma-route/
index.tsx # Composant de route
creer/
index.tsx # Route imbriquée
Modèle de Composant Moderne (Copie Rapide)
import React, { useState, useCallback } from 'react';
import { Box, Paper } from '@mui/material';
import { useSuspenseQuery } from '@tanstack/react-query';
import { featureApi } from '../api/featureApi';
import type { FeatureData } from '~types/fonctionnalite';
interface MonComposantProps {
id: number;
surAction?: () => void;
}
export const MonComposant: React.FC<MonComposantProps> = ({ id, surAction }) => {
const [etat, setEtat] = useState<string>('');
const { data } = useSuspenseQuery({
queryKey: ['feature', id],
queryFn: () => featureApi.getFeature(id),
});
const gererAction = useCallback(() => {
setEtat('mis à jour');
surAction?.();
}, [surAction]);
return (
<Box sx={{ p: 2 }}>
<Paper sx={{ p: 3 }}>
{/* Contenu */}
</Paper>
</Box>
);
};
export default MonComposant;
Pour des exemples complets, voir resources/complete-examples.md
Compétences Connexes
- error-tracking : Suivi des erreurs avec Sentry (s'applique aussi au frontend)
- backend-dev-guidelines : Modèles d'API backend que le frontend consomme
Statut de la Compétence : Structure modulaire avec chargement progressif pour une gestion optimale du contexte