Estándares de revisión de código para RN
Lista de verificación de revisión de rendimiento, accesibilidad y límite nativo para Expo SDK 57 PRs. Estandariza lo que los revisores verifican para que la calidad escale sin el tech lead en cada diff.
Busca en todas las páginas de la documentación
Lista de verificación de revisión de rendimiento, accesibilidad y límite nativo para Expo SDK 57 PRs. Estandariza lo que los revisores verifican para que la calidad escale sin el tech lead en cada diff.
Tarjeta de referencia rápida de revisión de PR - pega en
.github/pull_request_template.md.
## Lista de verificación de revisión móvil
### Evidencia (cambios de UI / gesto / accesibilidad)
- [ ] Captura de pantalla o grabación de iOS adjunta
- [ ] Captura de pantalla o grabación de Android adjunta
- [ ] Se anotó verificación puntual de VoiceOver O TalkBack (qué flujo)
### Rendimiento
- [ ] Las listas usan FlashList/FlatList - no ScrollView para feeds largos
- [ ] `renderItem` / `keyExtractor` estable (useCallback o scope del módulo)
- [ ] Sin nuevas importaciones pesadas en `app/_layout.tsx` sin lazy route
### Accesibilidad
- [ ] `accessibilityLabel` en controles solo con icono
- [ ] `accessibilityRole` coincide con el comportamiento (button vs link)
- [ ] Tipo dinámico: layout sobrevive a fuente grande (o `maxFontSizeMultiplier` justificado)
### Límite nativo
- [ ] Nuevas dependencias añadidas vía `npx expo install <pkg>`
- [ ] Cambios en `app.config.ts` / plugin de configuración llamados en la descripción
- [ ] Clasificado: solo JS (OTA OK) vs requiere `eas build`
- [ ] `npx expo-doctor` verde (enlace CI)
### Arquitectura
- [ ] Archivo de ruta delgada - lógica en `features/`
- [ ] Sin importaciones profundas entre límites de feature
- [ ] Estado del servidor en TanStack Query - no duplicado en Zustand
### Versión (si toca eas.json, runtimeVersion, channels)
- [ ] Pasos de reversión en ticket / comentario de PR
- [ ] Bump de runtimeVersion justificadoCuándo usarlo:
// ❌ El revisor bloquea - ScrollView map de 200 pedidos
export function OrdersScreenBad() {
const { data } = useOrders();
return (
<ScrollView>
{data?.map((o) => <OrderRow key={o.id} order={o} />)}
</ScrollView>
);
}// ✅ Ruta de aprobación - lista virtualizada + renderItem estable
import { FlashList } from "@shopify/flash-list";
import { useCallback } from "react";
export function OrdersScreen() {
const { data } = useOrders();
const renderItem = useCallback(
({ item }: { item: Order }) => <OrderRow order={item} />,
[]
);
return (
<FlashList
data={data ?? []}
renderItem={renderItem}
keyExtractor={(o) => o.id}
estimatedItemSize={72}
/>
);
}Preguntas del revisor:
renderItem en cada renderizado (arrow inline)?Consulta Performance Best Practices y Memory Leaks & List Churn.
// ❌ Bloquear - solo icono, sin nombre, rol incorrecto
<Pressable onPress={onSave}>
<Icon name="check" />
</Pressable>// ✅ Aprobar - nombre, rol, estado
<Pressable
onPress={onSave}
accessibilityRole="button"
accessibilityLabel="Save changes"
accessibilityState={{ disabled: !dirty, busy: saving }}
>
<Icon name="check" accessible={false} />
</Pressable>Verificación puntual del revisor (30 segundos):
Consulta accessibilityLabel & accessibilityRole.
// package.json - el revisor verifica expo install, no npm major sin procesar
+ "expo-camera": "~17.0.10"// app.config.ts - estrofa de plugin presente
plugins: [
[
"expo-camera",
{
cameraPermission: "Allow $(PRODUCT_NAME) to scan warehouse barcodes.",
},
],
],Lista de verificación del revisor:
| Pregunta | Criterios de aprobación |
|---|---|
| ¿Seguro para OTA? | No - módulo nativo; PR etiqueta requires-build |
| ¿Cadenas de permiso legibles por humanos? | Sí - revisión de tienda lee estas |
| ¿Prueba de Expo Go reclamada? | Bandera engañosa - necesita dev client |
| ¿ADR o ticket enlaza decisión nativa? | Architecture Decision Records |
// ❌ Bloquear - fetch + ramificación en ruta app/
// app/(tabs)/orders.tsx
export default function OrdersRoute() {
const [filter, setFilter] = useState("open");
const { data } = useQuery({ queryKey: ["orders", filter], queryFn: () => fetchOrders(filter) });
return <FlatList data={data} ... />;
}// ✅ Aprobar - ruta delgada
// app/(tabs)/orders.tsx
export { OrdersScreen as default } from "@/features/orders/screens/OrdersScreen";Se alinea con Mobile Architecture Basics y Feature-Sliced Design for RN.
| Severidad | Ejemplos | Acción |
|---|---|---|
| Bloquear | Plugin de permiso faltante; ScrollView feed; secreto en EXPO_PUBLIC_* | Debe corregirse antes de merge |
| Solicitar cambios | Props de lista inestables; etiqueta a11y faltante; importación de feature profunda | Corregir o ticket + seguimiento |
| Comentario | Nombres, refactor opcional, docs | Discreción del autor |
| Elogio | Tests, notas de reversión, evidencia de matriz de dispositivos | Refuerza comportamiento |
iOS Pro Max solo en sim - Layout y rendimiento engañan. Solución: Requiere evidencia de Android emu para UI PRs.
"LGTM" en PR de solo package.json - Deriva nativa sin plugin. Solución: Sección de límite nativo obligatoria cuando los cambios de lockfile incluyen paquetes nativos de expo-*.
Revisar captura de pantalla de Expo Go para bug de reanimated worklet - Dev client difiere. Solución: Enlace de preview build en PR.
Aprobar caché de Zustand de lista de API - Duplica fuente de verdad. Solución: Señala ADR: State Management Selection.
Saltar reversión en cambio de canal eas.json - Usuarios incorrectos obtienen update. Solución: Subsección de versión requerida.
| Enfoque | Usar cuando | No uses cuando |
|---|---|---|
| Checklist de plantilla PR | Default - baja fricción | Equipos solo con diff visual completamente automatizado |
| Danger / bot personalizado | Aplica etiquetas de captura de pantalla | Equipo pequeño - costo de mantenimiento |
| Solo revisión por pares | Migración nativa compleja | Throughput de feature diario |
CODEOWNERS en app.config.ts | Monorepo multi-squad | Overhead de mantenedor solo |
Para PRs de configuración nativa y gesto - sí. Para solo TSX de copia, evidencia de dispositivo en PR es suficiente si CI es verde.
Target mismo día laboral para PRs bajo 400 líneas. Si es más largo, el autor debe dividir o programar pairing de revisión.
Alternar por PR está bien; ambas plataformas deben cubrirse en el sprint - no solo iOS.
Salta revisar línea por línea .expo/types; sí verifica que tsc pase y route params coincidan con uso.
Mismo checklist; los seniors escalan elementos de arquitectura y límite nativo. Los juniors se enfocan en patrones de a11y y lista primero - Junior - Mid RN Leveling.
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