11 · React Native
3va can’t render React Native: that needs the native bridge and Metro. Much of an RN app is plain TypeScript, though: reducers, selectors, form validation, formatting, the API client. 3va runs and tests that part directly, and the same modules can be shared with a backend.
Source: examples/11-react-native
src/
todos.ts todo-list reducer + selectors (pure TS)
validate.ts signup form validation (shared with the backend)
index.ts runnable demo
todos.test.ts Jest-compatible testsRun the demo
cd examples/11-react-native
3va run src/index.ts --allow-read=./src=== Lógica compartida React Native, ejecutada con 3va ===
Tareas: 3
[x] Revisar el PR de auth
[ ] Diseñar el onboarding
[ ] Actualizar iconos
Progreso: ███░░░░░░░ 33% (1/3)
Creadas en el último minuto: 3
Errores de validación del formulario de registro:
email: Email no válido
password: Mínimo 8 caracteres
confirmPassword: Las contraseñas no coinciden(The example’s strings are in Spanish.) The demo dispatches four add
actions, one of them blank (" "), which the reducer ignores, so there
are 3 tasks. Then it toggles the first one.
Run the tests
3va test ✓ todoReducer > agrega una tarea limpia (trim) y asigna id
✓ todoReducer > ignora tareas vacías
✓ todoReducer > toggle marca/desmarca una tarea
✓ todoReducer > remove elimina la tarea exacta
✓ todoReducer > clear-done elimina solo las completadas
✓ selectProgress / prettyProgress > progreso 50% con una de dos hecha
✓ selectProgress / prettyProgress > prettyProgress dibuja la barra y el conteo
✓ validateSignup > email inválido
✓ validateSignup > password débil
✓ validateSignup > contraseñas que no coinciden
Tests: 10
Passed: 10How it works
The reducer is an ordinary pure function over a discriminated union, the
same kind of code you’d pass to useReducer in a component:
export type TodoAction =
| { type: "add"; text: string }
| { type: "toggle"; id: string }
| { type: "remove"; id: string }
| { type: "clear-done" };
export function todoReducer(state: Todo[], action: TodoAction): Todo[] { … }It imports nothing from react-native, so 3va can load it. The component
calls useReducer(todoReducer, []), and a test calls todoReducer directly.
In a real React Native project
npx react-native run-android # native build + Metro: still RN's own tooling
3va install # dependencies (no postinstall scripts)
3va run scripts/generate-types.ts # codegen / config scripts
3va test # the Jest suite for your pure logicThings to keep in mind
- Only modules with no native imports can run. Anything that imports
react-native,expo-*native modules, orNativeModuleswon’t run under 3va. Keep business logic in separate files that don’t import those, which is good design anyway. --allow-read=./srcis needed for3va runbecauseindex.tsimports./todosand./validate. Without it:Permission denied: --allow-read=…/src/todos.ts is required.3va testdidn’t need it.- Your existing Jest setup doesn’t carry over.
jest.config.js,preset: "react-native",jest.mock(...)of native modules and@testing-library/react-nativecomponent tests belong in the RN Jest setup. Use3va testfor the pure-logic suite. - Time-dependent code:
selectDueSoonand the ID generator useDate.now(). The tests avoid asserting exact IDs and timestamps. Do the same, or inject the clock.