5.5 KiB
Frontend — Risques & vigilance : Navigation
Extrait de la base de connaissance Lead_tech. Voir
knowledge/frontend/risques/README.mdpour l'index complet.
Écran détail Expo Router — store vide en deep link / reload
Risques
- L'écran détail (
[slug].tsx) lit ses données depuis un store Zustand peuplé par l'écran liste - En deep link, kill + reopen ou navigation OS back, le store est vide → "introuvable" affiché à tort
Symptômes
- Écran détail vide ou erreur "non trouvé" sur accès direct (pas via la liste)
- Fonctionne normalement en navigation standard mais échoue sur reload
Bonnes pratiques / mitigations
// useEffect de secours dans l'écran détail
useEffect(() => {
if (!accessToken) return;
if (items.length > 0 || isLoading || errorState) return;
void fetchItems(accessToken);
}, [accessToken, items.length, isLoading, errorState, fetchItems]);
- Ne pas afficher "introuvable" avant d'avoir vérifié que le store a bien été peuplé
- Contexte technique : Expo Router / Zustand — app-alexandrie story 4.1, 20-03-2026
useEffect fetch — guard incomplet sur les états terminaux
Risques
- Si l'état "zéro résultat intentionnel" (ex :
paywallRequired) n'est pas dans les conditions de court-circuit, le fetch est re-déclenché à chaque re-render ou focus - Boucle de fetch infini sur un état métier normal
Symptômes
forums.length === 0etisLoading === false→ le guard ne court-circuite pas → fetch re-déclenché en boucle- Visible en focus sur l'écran depuis un autre onglet
Bonnes pratiques / mitigations
// ❌ Pattern à risque — re-fetch si paywallRequired (forums vide + isLoading false)
if (forums.length > 0 || isLoading) return;
// ✅ Pattern correct — court-circuit sur l'état terminal
if (forums.length > 0 || isLoading || paywallRequired) return;
Règle : les états "zéro résultat intentionnel" (liste vide + flag métier) doivent être traités comme "données présentes" dans le guard de fetch.
- Contexte technique : React Native / Zustand / Expo Router — app-alexandrie story 4.1, 20-03-2026
Store Zustand : collections sans clé de contexte (navigation inter-contexte)
Risques
- Un store qui stocke des collections dépendant d'un paramètre de navigation (forumSlug, threadId...) sans stocker ce paramètre affiche des données périmées lors d'une navigation inter-contexte
Symptômes
- Naviguer du forum A vers le forum B affiche encore les catégories/threads du forum A
- Guard
if (items.length > 0) returnempêche le rechargement lors d'un changement de contexte
Bonnes pratiques / mitigations
-
Stocker la clé de contexte avec les données :
categoriesForumSlug: string | null -
Invalider si
categoriesForumSlug !== currentForumSlugavant de retourner depuis le cache -
Ou supprimer le guard et dépendre uniquement du changement de paramètre dans le
useEffect -
Contexte technique : React Native / Zustand / Expo Router — app-alexandrie 23-03-2026
Expo Router — mapping name/label des tabs inversés sans erreur
Risques
<Tabs.Screen name="x">route versapp/(tabs)/x.tsx— letitle(label affiché) est totalement indépendant du routage- Un label "Communauté" sur
name="explore"afficheexplore.tsxsans aucune erreur de build ni de lint
Symptômes
- Le bon label est affiché, mais l'écran affiché est celui d'un boilerplate ou d'un autre module
- Bug invisible jusqu'au test manuel de chaque onglet
Bonnes pratiques / mitigations
-
Lors de tout ajout ou renommage de tab, valider visuellement que chaque label correspond à l'écran attendu
-
Convention : aligner le
nameet le nom de fichier avec le wording du label (ex :name="community"→community.tsx→title="Communauté") -
Ajouter un test de smoke de navigation si la structure de tabs est critique
-
Contexte technique : Expo Router — app-alexandrie, 25-03-2026
Expo Router — ne jamais préfixer le groupe dans router.push
Risques
router.push('/(auth)/forgot-password')depuis un écran(tabs)/peut échouer silencieusement ou lever une erreur selon la version d'Expo Router- La résolution des groupes de routes se fait par contexte de navigation — un préfixe de groupe explicite n'est pas un chemin de route valide
Symptômes
- Navigation vers un écran
(auth)/qui n'aboutit pas ou lève une erreur au runtime - Fonctionne dans certaines versions d'Expo Router mais pas d'autres
Bonnes pratiques / mitigations
// ❌ Anti-pattern — préfixe de groupe explicite
router.push('/(auth)/forgot-password');
// ✅ Pattern correct — chemin sans groupe
router.push('/forgot-password' as never);
-
Règle : les groupes
(auth),(tabs), etc. sont des conventions d'organisation de fichiers, pas des segments de route — ne jamais les inclure dans les appels de navigation programmatique -
Contexte technique : Expo Router — app-alexandrie, 25-03-2026