Mejores Vistas de Lista en React Native
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Muchos de ustedes ya han empezado a probar nuestros nuevos componentes de lista tras nuestro anuncio preliminar en el grupo comunitario, ¡pero hoy los anunciamos oficialmente! Adiós a los ListView, DataSource, filas obsoletas, errores ignorados y consumo excesivo de memoria. Con el último candidato a lanzamiento de React Native de marzo 2017 (0.43-rc.1), puedes elegir entre esta nueva suite de componentes lo que mejor se adapte a tu caso de uso, con gran rendimiento y funciones listas para usar:
<FlatList>
Este es el componente de trabajo para listas simples y de alto rendimiento. Proporciona un array de datos y una función renderItem, y listo:
<FlatList
data={[{title: 'Title Text', key: 'item1'}, ...]}
renderItem={({item}) => <ListItem title={item.title} />}
/>
<SectionList>
Si necesitas renderizar datos organizados en secciones lógicas (como en una agenda alfabética con encabezados), o con datos heterogéneos y renderizados diversos (por ejemplo: una vista de perfil con botones, seguida de un compositor, luego una cuadrícula de fotos, otra de amigos y finalmente historias), esta es la opción ideal.
<SectionList
renderItem={({item}) => <ListItem title={item.title} />}
renderSectionHeader={({section}) => <H1 title={section.key} />}
sections={[ // homogeneous rendering between sections
{data: [...], key: ...},
{data: [...], key: ...},
{data: [...], key: ...},
]}
/>
<SectionList
sections={[ // heterogeneous rendering between sections
{data: [...], key: ..., renderItem: ...},
{data: [...], key: ..., renderItem: ...},
{data: [...], key: ..., renderItem: ...},
]}
/>
<VirtualizedList>
La implementación subyacente con una API más flexible. Especialmente útil cuando tus datos no están en un array simple (ej. una lista inmutable).
Características
Dado que las listas se usan en muchos contextos, hemos equipado los nuevos componentes con funciones para cubrir la mayoría de casos de uso:
-
Carga al hacer scroll (
onEndReached). -
Pull to refresh (
onRefresh/refreshing). -
Callbacks de visibilidad (VPV) configurables (
onViewableItemsChanged/viewabilityConfig). -
Modo horizontal (
horizontal). -
Separadores inteligentes de ítems y secciones.
-
Soporte multicolumna (
numColumns) -
scrollToEnd,scrollToIndexyscrollToItem -
Mejor tipado con Flow.
Consideraciones importantes
-
El estado interno de los subcomponentes no se preserva al salir de la ventana de renderizado. Asegúrate de capturar todos los datos en el ítem o almacenes externos como Flux, Redux o Relay.
-
Estos componentes se basan en
PureComponent, lo que significa que no se rerenderizarán si lospropspermanecen superficialmente iguales. Asegúrate que todo lo que usa tu funciónrenderItemse pase como prop que no sea===tras actualizaciones, o tu UI podría no actualizarse. Esto incluye el propdatay el estado del componente padre. Ejemplo:<FlatList
data={this.state.data}
renderItem={({item}) => (
<MyItem
item={item}
onPress={() =>
this.setState(oldState => ({
selected: {
// New instance breaks `===`
...oldState.selected, // copy old data
[item.key]: !oldState.selected[item.key], // toggle
},
}))
}
selected={
!!this.state.selected[item.key] // renderItem depends on state
}
/>
)}
selected={
// Can be any prop that doesn't collide with existing props
this.state.selected // A change to selected should re-render FlatList
}
/> -
Para optimizar memoria y permitir scroll fluido, el contenido se renderiza asíncronamente fuera de pantalla. Esto puede causar que al hacer scroll muy rápido aparezca contenido vacío momentáneamente. Es una compensación ajustable por aplicación, y estamos trabajando en mejoras internas.
-
Por defecto, estas listas buscan una prop
keyen cada ítem para la clave de React. Alternativamente, puedes usarkeyExtractor.
Rendimiento
Además de simplificar la API, los nuevos componentes de lista también ofrecen mejoras significativas de rendimiento, siendo la principal un uso de memoria casi constante para cualquier cantidad de filas. Esto se logra "virtualizando" elementos fuera de la ventana de renderizado desmontándolos completamente de la jerarquía de componentes y liberando la memoria JS de los componentes React, junto con la memoria nativa del shadow tree y las vistas de UI. Esto tiene una salvedad: el estado interno del componente no se conservará, así que asegúrate de guardar cualquier estado importante fuera de los componentes mismos, por ejemplo en almacenes de Relay, Redux o Flux.
Limitar la ventana de renderizado también reduce el trabajo requerido por React y la plataforma nativa, como en recorridos de vistas. Incluso al renderizar el último de un millón de elementos, con estas nuevas listas no necesitas iterar todos los elementos para renderizar. Puedes saltar al centro con scrollToIndex sin renderizado excesivo.
También mejoramos la programación para aumentar la capacidad de respuesta de las aplicaciones. Los elementos en el borde de la ventana de renderizado se procesan con menos frecuencia y menor prioridad, después de completarse gestos, animaciones u otras interacciones activas.
Uso Avanzado
A diferencia de ListView, todos los elementos en la ventana de renderizado se vuelven a renderizar cuando cambian las props. Suele ser aceptable porque la ventana reduce los elementos a una cantidad constante, pero si tus elementos son complejos, sigue las mejores prácticas de React para rendimiento usando React.PureComponent y/o shouldComponentUpdate según corresponda en tus componentes para limitar re-renderizados del subárbol recursivo.
Si puedes calcular la altura de tus filas sin renderizarlas, mejora la experiencia del usuario proporcionando la prop getItemLayout. Esto suaviza el desplazamiento a elementos específicos con ej. scrollToIndex, y mejora la UI del indicador de scroll al determinar la altura del contenido sin renderizarlo.
Para tipos de datos alternativos como listas inmutables, usa <VirtualizedList>. Toma una prop getItem que devuelve datos del elemento para cualquier índice, con tipado de Flow más flexible.
Hay múltiples parámetros ajustables para casos inusuales: usa windowSize para equilibrar memoria/experiencia de usuario, maxToRenderPerBatch para ajustar tasa de llenado/capacidad de respuesta, onEndReachedThreshold para controlar la carga al desplazar, y más.
Trabajo Futuro
-
Migración de superficies existentes (y eventual depreciación de
ListView). -
Más características según necesidades detectadas (¡coméntanos!).
-
Soporte para encabezados de sección fijos (sticky).
-
Más optimizaciones de rendimiento.
-
Soporte para componentes funcionales de elemento con estado.