>_ DevTrendspt

Idioma

Início

Linguagens

Seções

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embarcados Segurança
TypeScript

Listas Rápidas no React Native Sem Gambiarras de Tamanho ou Módulos Nativos

Se você já construiu uma interface complexa no React Native, provavelmente já xingou as listas. O FlatList padrão começa a perder FPS em listas longas e entope a memória. O FlashList da Shopify é notavelmente mais rápido graças à reutilização de componentes, mas tente alimentá-lo com elementos de altura imprevisível como posts com quantidades variadas de texto e imagens. Micro-travamentos durante rolagem rápida ou tremores de layout começam quando a lista tenta adivinhar tamanhos de células através de estimatedItemSize.

Recentemente, a equipe da LegendApp lançou a biblioteca Legend List. É um componente de lista escrito inteiramente em TypeScript, sem uma única linha de código nativo, que resolve exatamente essa dor de cabeça de dimensionamento dinâmico.

O Conceito

O principal objetivo do projeto é fornecer uma substituição para FlatList e FlashList com uma API familiar, mas sem quedas de desempenho em elementos de altura variável. Os desenvolvedores usaram deliberadamente apenas JavaScript e TypeScript puro. Nenhum módulo nativo precisa ser vinculado. Isso simplifica a construção para Expo Go e versões web, e também reduz o risco de quebrar algo ao atualizar a versão do React Native.

O projeto é leve e funciona como uma substituição direta. Se você já tem uma tela escrita com FlatList, uma migração básica só requer mudar o import e o nome do componente.

O Que a Biblioteca Pode Fazer

Os desenvolvedores focaram em problemas típicos com listas em aplicativos móveis. Aqui estão quatro coisas que são notavelmente mais convenientes aqui:

  1. Altura dinâmica pronta para uso. Você não precisa pré-calcular dimensões exatas dos cards ou passar estimativas aproximadas. A lista se adapta aos tamanhos do conteúdo por conta própria sem atraso de renderização.

  2. Interface de chat adequada. O truque clássico para criar uma tela de mensagens é inverter a lista através de inverted. Isso causa bugs estranhos com animações de teclado, rolagem invertida e posicionamento. Legend List tem um prop alignItemsAtEnd que alinha o conteúdo na borda inferior sem inversão, e maintainScrollAtEnd que mantém a rolagem na última mensagem quando novos dados chegam.

  3. Rolagem infinita bidirecional. O carregamento de dados para cima e para baixo funciona sem flashes de tela branca e saltos abruptos na posição da viewport.

  4. Reciclagem controlada de células. Através do prop recycleItems, você pode ativar ou desativar a reutilização de componentes. Se um estado local complexo useState for armazenado dentro de um elemento de lista, a reutilização às vezes leva a efeitos colaterais desagradáveis com a exibição do estado de outra pessoa. Na Legend List, a reciclagem é desativada por padrão para segurança, mas você pode ativá-la com uma única linha para velocidade máxima.

Como Isso Fica no Código

A instalação é padrão:

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

Importamos o componente da subpasta runtime e passamos props familiares:

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

O prop maintainVisibleContentPosition mantém o conteúdo na tela se os tamanhos dos elementos acima da área visível mudarem ou novos dados chegarem.

Limitações e Planos

O repositório é jovem, apareceu no final de 2024. No roadmap, os autores declaram abertamente o que ainda não existe:

  • Grids masonry (tiles de alturas variadas)
  • Cabeçalhos fixos
  • Spans de colunas
  • Tipos de itens separados (getItemType)

Se sua tela depende de um grid complexo com seções fixas, é cedo demais para migrar.

Quem Deveria Experimentar

A biblioteca é útil para quem está cansado de lutar contra saltos de interface em chats, feeds de notícias ou listas de comentários. Se o FlashList apresenta tremores em seus cards dinâmicos e o FlatList não oferece a suavidade necessária, instale @legendapp/list em um branch de teste. Leva alguns minutos para verificar já que você não precisará mudar a estrutura do componente ou escrever wrappers nativos.

Projetos relacionados