>_ DevTrendspl

Język

Strona główna

Języki

Sekcje

Frontend Backend Mobilne DevOps AI / ML GameDev Blockchain Systemy wbudowane Bezpieczeństwo
TypeScript

Szybkie listy w React Native bez obejść rozmiarów ani modułów natywnych

Jeśli kiedykolwiek budowałeś złożony interfejs w React Native, prawdopodobnie przeklinałeś listy. Standardowy FlatList zaczyna tracić klatki na sekundę na długich listach i przepełnia pamięć. FlashList od Shopify jest zauważalnie szybszy dzięki ponownemu użyciu komponentów, ale spróbuj nakarmić go elementami o nieprzewidywalnej wysokości, takimi jak posty z różną ilością tekstu i obrazów. Mikrozamrożenia podczas szybkiego przewijania lub drżenie układu zaczynają się, gdy lista próbuje odgadnąć rozmiary komórek przez estimatedItemSize.

Ostatnio zespół LegendApp wydał bibliotekę Legend List. Jest to komponent listowy napisany w całości w TypeScripcie, bez ani jednej linii kodu natywnego, który rozwiązuje dokładnie ten problem z dynamicznym rozmiarem.

Koncepcja

Głównym celem projektu jest zapewnienie zamiennika dla FlatList i FlashList z znajomym API, ale bez spadków wydajności na elementach o zmiennej wysokości. Deweloperzy celowo użyli tylko czystego JavaScriptu i TypeScripta. Nie trzeba linkować żadnych modułów natywnych. Uproszcza to budowanie dla Expo Go i wersji webowych, a także zmniejsza ryzyko zepsucia czegoś podczas aktualizacji wersji React Native.

Projekt jest lekki i działa jako zamiennik typu drop-in. Jeśli masz już ekran napisany z FlatList, podstawowa migracja wymaga tylko zmiany importu i nazwy komponentu.

Co potrafi biblioteka

Deweloperzy skupili się na typowych problemach z listami w aplikacjach mobilnych. Oto cztery rzeczy, które są tutaj zauważalnie wygodniejsze:

  1. Dynamiczna wysokość out of the box. Nie musisz wcześniej obliczać dokładnych wymiarów kart ani przekazywać przybliżonych szacunków. Lista sama dostosowuje się do rozmiarów treści bez opóźnień renderowania.

  2. Właściwy interfejs czatu. Klasyczna sztuczka do tworzenia ekranu wiadomości polega na odwróceniu listy przez inverted. Powoduje to dziwne błędy z animacjami klawiatury, odwróconym przewijaniem i pozycjonowaniem. Legend List ma właściwość alignItemsAtEnd, która wyrównuje treść do dolnej krawędzi bez odwracania, oraz maintainScrollAtEnd, która utrzymuje przewijanie na ostatniej wiadomości, gdy nadejdą nowe dane.

  3. Dwukierunkowe nieskończone przewijanie. Ładowanie danych w górę i w dół działa bez błysków białego ekranu i gwałtownych skoków pozycji widoku.

  4. Kontrolowane recykling komórek. Poprzez właściwość recycleItems możesz włączyć lub wyłączyć ponowne użycie komponentów. Jeśli złożony lokalny useState jest przechowywany wewnątrz elementu listy, ponowne użycie czasami prowadzi do nieprzyjemnych efektów ubocznych z wyświetlaniem stanu kogoś innego. W Legend List recykling jest domyślnie wyłączony dla bezpieczeństwa, ale możesz go włączyć jedną linią dla maksymalnej szybkości.

Jak to wygląda w kodzie

Instalacja jest standardowa:

npm install @legendapp/list
# или через bun / yarn
bun add @legendapp/list

Importujemy komponent z podfolderu runtime i przekazujemy znajome właściwości:

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 },
})

Właściwość maintainVisibleContentPosition utrzymuje treść na ekranie, jeśli rozmiary elementów powyżej widocznego obszaru się zmienią lub nadejdą nowe dane.

Ograniczenia i plany

Repozytorium jest młode, pojawiło się pod koniec 2024 roku. W roadmapzie autorzy otwarcie stwierdzają, czego jeszcze nie ma:

  • Siatki typu masonry (kafelki o różnych wysokościach)
  • Przyklejone nagłówki
  • Zakresy kolumn
  • Oddzielne typy elementów (getItemType)

Jeśli Twój ekran opiera się na złożonej siatce z przyklejonymi sekcjami, jest za wcześnie na migrację.

Kto powinien spróbować

Biblioteka jest przydatna dla tych, którzy mają dość walki ze skokami interfejsu na czatach, kanałach informacyjnych lub listach komentarzy. Jeśli FlashList podskakuje na Twoich dynamicznych kartach, a FlatList nie zapewnia płynności, której potrzebujesz, zainstaluj @legendapp/list w gałęzi testowej. zajmie to tylko kilka minut do sprawdzenia, ponieważ nie będziesz musiał zmieniać struktury komponentów ani pisać natywnych wrapperów.

Powiązane projekty