Mejores prácticas para listas
Un resumen condensado de las 25 mejores prácticas más importantes extraídas de cada página en esta sección.
Busca en todas las páginas de la documentación
Un resumen condensado de las 25 mejores prácticas más importantes extraídas de cada página en esta sección.
Elige ScrollView para contenido estático pequeño: Menos de ~20 elementos que no crecen con tipos de layout mixtos - una vez que la lista crece o se pagina, cambia a virtualización.
Usa FlatList por defecto para feeds: FlatList recicla filas fuera de pantalla - mapear cientos de elementos dentro de ScrollView asigna cada fila en memoria e bloquea el hilo JS.
Evalúa FlashList para feeds pesados: En SDK 57, Shopify FlashList mejora el rendimiento de reciclaje cuando los perfiles muestran caídas de fotogramas - migra con estimatedItemSize y una lista de verificación de migración medida.
Las claves deben ser cadenas estables: keyExtractor debe devolver ids del servidor - las claves de índice rompen la selección, animación y estado cuando los elementos se ordenan, filtran o paginan.
Nunca uses el índice del array como clave para datos dinámicos: key={index} hace que el contenido incorrecto de la fila parpadee durante inserción/eliminación - los usuarios ven que los likes saltan entre publicaciones.
Extrae renderItem a una fila memoizada: Los cierres de renderItem en línea se recrean en cada renderizado del padre - const Row = memo(function Row…) más un manejador useCallback estable.
Pasa extraData cuando la selección controla la interfaz: Sin extraData, FlatList puede omitir el re-renderizado de filas visibles después de que selectedId cambia - pasa el slice de estado mínimo que afecta la apariencia de la fila.
Eleva los estilos de lista a StyleSheet: contentContainerStyle={{ padding: 16 }} fresco en cada renderizado del padre invalida las optimizaciones de lista - almacena en caché los estilos del contenedor.
Usa getItemLayout para filas de altura fija: Las filas de bandeja de entrada y configuración con altura uniforme omiten la medición asincrónica - desplazarse a un índice se vuelve instantáneo.
No mientas a getItemLayout: Una length u offset incorrecta produce espacios en blanco y desplazamiento entrecortado - mide una vez en la revisión de diseño y mantén la altura sincronizada con los separadores.
Separa los estados vacío y de carga: ListEmptyComponent no debe girar forever - ramifica ListEmptyComponent vs esqueletos de ListFooterComponent mientras se carga la primera página.
Pull-to-refresh reinicia la paginación: onRefresh debe limpiar el estado del cursor y recargar la página uno - agregar a un cursor obsoleto después de la actualización duplica elementos.
Protege onEndReached: Dispara solo cuando !isFetching && hasNextPage - de lo contrario, el desplazamiento con momentum dispara recuperaciones de página duplicadas en la parte inferior.
Muestra esqueletos de pie de página para paginación: Una pequeña fila de carga en ListFooterComponent es mejor que un spinner de pantalla completa para la página dos - los usuarios mantienen el contexto en el feed.
Precomputa secciones de SectionList en useMemo: Agrupar cientos de elementos en render asigna en cada paso - deriva sections cuando los datos de origen o el orden de clasificación cambian.
Usa encabezados pegajosos intencionalmente: stickySectionHeadersEnabled ayuda con listas alfabéticas - deshabilita cuando los encabezados se superponen con contenido complejo en la parte superior.
Habilita nestedScrollEnabled para rieles horizontales: Feed vertical - estante horizontal necesita desplazamiento anidado explícito en Android - prueba el handoff de gesto en dispositivos reales.
Evita FlatList vertical dentro de ScrollView vertical: Los contenedores de desplazamiento doble luchan contra gestos y rompen la virtualización - un eje debe ser propietario del desplazamiento; usa solo listas internas horizontales.
Ajusta windowSize después del perfil: Reducir windowSize reduce la memoria; demasiado bajo causa filas en blanco durante flings rápidos - comienza con los valores predeterminados, ajusta con Flashlight o RN DevTools.
Establece FlashList estimatedItemSize cerca de la realidad: Las estimaciones alejadas de la altura medida causan thrashing de layout y fotogramas en blanco - mide la altura promedio de la fila del contenido de producción.
Evita funciones anónimas en renderItem: onPress={() => toggle(item.id)} dentro de filas anula memo - pasa id a las filas que llaman manejadores estables.
Valida alturas dinámicas de fila: Las filas de altura variable sin medición causan que la virtualización monte contenido incorrecto - usa FlashList overrideItemLayout o acepta secciones no virtualizadas.
Prueba rotación y escala de fuente en listas: Las fuentes de accesibilidad más grandes cambian la altura de la fila - getItemLayout fijo puede necesitar medición dinámica o constantes actualizadas.
Desplázate a la parte superior en re-tap de pestaña vía ref: Expone flatListRef.current?.scrollToOffset({ offset: 0 }) desde eventos de navegación - las aplicaciones de feed esperan este comportamiento.
Ejecuta la lista de verificación de trampas de virtualización antes del lanzamiento: Revisa claves, alturas, estados vacíos y casos de desplazamiento anidado en un dispositivo Android de gama baja - los simuladores ocultan errores de filas en blanco.
FlatList hasta que el perfil pruebe entrecortamiento en dispositivos objetivo.getItemLayout, aumenta windowSize ligeramente o mejora FlashList estimatedItemSize - los espacios en blanco casi siempre son matemáticas de altura, no "React siendo lento."Versiones de stack: Esta página fue escrita para React 19.2.3, React Native 0.86.0 y Expo SDK 57 (
expo~57.0.4).
Revisado por Chris St. John·Última actualización: 16 jul 2026