Listes Rapides dans React Native Sans Contournements de Dimensionnement ni Modules Natifs
Si vous avez déjà construit une interface complexe dans React Native, vous avez probablement pesté contre les listes. Le FlatList standard commence à perdre des FPS sur les longues listes et surcharge la mémoire. FlashList de Shopify est заметно plus rapide grâce à la réutilisation des composants, mais essayez de lui donner des éléments de hauteur imprévisible comme des publications avec des quantités variables de texte et d'images. Des micro-saccades pendant le défilement rapide ou des sautillements de mise en page commencent lorsque la liste essaie de deviner les tailles des cellules via estimatedItemSize.
Récemment, l'équipe LegendApp a publié la bibliothèque Legend List. C'est un composant de liste écrit entièrement en TypeScript, sans une seule ligne de code natif, qui résout exactement ce mal de tête du dimensionnement dynamique.
Le Concept
Le objectif principal du projet est de fournir un remplacement pour FlatList et FlashList avec une API familière, mais sans baisse de performance sur les éléments de hauteur variable. Les développeurs ont délibérément utilisé uniquement du JavaScript et TypeScript pur. Aucun module natif n'a besoin d'être lié. Cela simplifie la construction pour Expo Go et les versions web, et réduit également le risque de casser quelque chose lors de la mise à jour de la version de React Native.
Le projet est léger et fonctionne comme un remplacement direct. Si vous avez déjà un écran écrit avec FlatList, une migration basique ne nécessite que de changer l'import et le nom du composant.
Ce Que la Bibliothèque Peut Faire
Les développeurs se sont concentrés sur les problèmes typiques avec les listes dans les applications mobiles. Voici quatre choses qui sont sensiblement plus pratiques ici :
Hauteur dynamique prête à l'emploi. Vous n'avez pas besoin de pré-calculer les dimensions exactes des cartes ou de passer des estimations approximatives. La liste s'adapte aux tailles du contenu toute seule sans décalage de rendu.
Interface de chat appropriée. L'astuce classique pour créer un écran de messagerie est de retourner la liste via
inverted. Cela provoque des bugs étranges avec les animations du clavier, le défilement inversé et le positionnement. Legend List a une propalignItemsAtEndqui aligne le contenu sur le bord inférieur sans inversion, etmaintainScrollAtEndqui maintient le défilement au dernier message lorsque de nouvelles données arrivent.Défilement infini bidirectionnel. Le chargement des données vers le haut et vers le bas fonctionne sans flash d'écran blanc et sans sauts abrupts de position de la fenêtre d'affichage.
Recyclage contrôlé des cellules. À travers la prop
recycleItems, vous pouvez activer ou désactiver la réutilisation des composants. Si un état local complexeuseStateest stocké à l'intérieur d'un élément de liste, la réutilisation conduit parfois à des effets secondaires désagréables avec l'affichage de l'état de quelqu'un d'autre. Dans Legend List, le recyclage est désactivé par défaut pour la sécurité, mais vous pouvez l'activer avec une seule ligne pour une vitesse maximale.
À Quoi Ça Ressemble dans le Code
L'installation est standard :
npm install @legendapp/list
# или через bun / yarn
bun add @legendapp/list
Nous importons le composant depuis le sous-dossier runtime et passons des props familières :
import React, { useRef } from "react"
import { View, Image, Text, StyleSheet } from "react-native"
import { LegendList, LegendListRef, LegendListRenderItemProps } from "@legendapp/list/react-native"
interface PostItem {
id: string
author: string
content: string
photoUrl?: string
}
export const FeedScreen = ({ posts }: { posts: PostItem[] }) => {
const listRef = useRef<LegendListRef | null>(null)
const renderItem = ({ item }: LegendListRenderItemProps<PostItem>) => {
return (
<View style={styles.card}>
<Text style={styles.author}>{item.author}</Text>
<Text style={styles.text}>{item.content}</Text>
{item.photoUrl && (
<Image source={{ uri: item.photoUrl }} style={styles.image} />
)}
</View>
)
}
return (
<LegendList
data={posts}
renderItem={renderItem}
keyExtractor={(item) => item.id}
recycleItems={true}
maintainVisibleContentPosition
ref={listRef}
/>
)
}
const styles = StyleSheet.create({
card: { padding: 16, borderBottomWidth: 1, borderColor: "#eee" },
author: { fontWeight: "bold", marginBottom: 4 },
text: { fontSize: 14, lineHeight: 20 },
image: { width: "100%", height: 200, marginTop: 8, borderRadius: 8 },
})
La prop maintainVisibleContentPosition garde le contenu à l'écran si les tailles des éléments au-dessus de la zone visible changent ou si de nouvelles données arrivent.
Limitations et Plans
Le dépôt est récent, il est apparu à la fin de 2024. Dans la feuille de route, les auteurs déclarent ouvertement ce qui n'existe pas encore :
- Grilles en maçonnerie (tuiles de hauteurs variables)
- En-têtes collants
- Étendues de colonnes
- Types d'éléments séparés (
getItemType)
Si votre écran repose sur une grille complexe avec des sections collantes, il est trop tôt pour migrer.
Qui Devrait Essayer
La bibliothèque est utile pour ceux qui en ont marre de lutter contre les sauts d'interface dans les chats, les fils d'actualité ou les listes de commentaires. Si FlashList saccade sur vos cartes dynamiques et que FlatList ne fournit pas la fluidité dont vous avez besoin, installez @legendapp/list dans une branche de test. Cela prend quelques minutes à vérifier puisque vous n'aurez pas besoin de changer la structure des composants ou d'écrire des wrappers natifs.
Projets similaires