Ceci s’est avéré être une vilaine « condition de concurrence » entre le « sentinelle » que nous utilisons pour détecter quand nous devons déclencher l’action « charger plus » et le rendu des lignes dans le répertoire des utilisateurs ![]()
Le problème
Quand il y avait au moins 50 utilisateurs, la page /u (répertoire des utilisateurs) déclenchait loadMore immédiatement au premier chargement, avant que l’utilisateur ne puisse faire défiler la page. Cela entraînait le chargement automatique d’une deuxième page de résultats indésirable.
Cause profonde
Condition de concurrence de synchronisation lors du chargement initial de la page :
- L’utilisateur navigue vers
/u controllers/userscommence à charger les données (isLoading: true)- Le modèle se rend avec
ConditionalLoadingSpinneraffichant le spinner - Les données arrivent,
isLoadingdevientfalse - Le spinner se masque,
DirectoryTablecommence à rendre 50 utilisateurs - L’élément sentinelle LoadMore est inséré dans le DOM
- IntersectionObserver est créé et commence à observer immédiatement
- À ce moment, le tableau calcule encore la mise en page/s’étend à sa pleine hauteur
- Le sentinelle est brièvement visible dans le viewport (~292px du haut) avant que le tableau ne s’étende
- L’observateur détecte l’intersection → déclenche
loadMore
- Le tableau finit de s’étendre à sa pleine hauteur (~3689px)
- Le sentinelle se déplace à la bonne position (~3959px, sous le viewport)
L’observateur était « trop impatient » - il a commencé à observer avant que le contenu n’ait fini sa mise en page, capturant le sentinelle pendant le bref moment où le tableau n’avait pas encore atteint sa hauteur finale.
La correction
Retarder la création de l’observateur jusqu’à ce que le contenu soit prêt :
Ajout d’un paramètre @isLoading à LoadMore qui empêche la création de IntersectionObserver lorsque le contenu est encore en cours de chargement.
Comment ça marche maintenant
Chargement de la page → isLoading=true → Le modificateur saute la création de l'observateur
↓
Chargement des données → isLoading=false → Le modificateur s'exécute à nouveau, crée l'observateur
↓
Tableau entièrement étendu → Sentinelle à la bonne position (sous le viewport)
↓
L'utilisateur fait défiler la page → Le sentinelle entre dans le viewport → loadMore se déclenche ✓