Concepto clave
El almacenamiento local es como la memoria de corto plazo de tu aplicacion movil. Mientras que las APIs externas son como consultar una biblioteca remota, el almacenamiento local es tu cuaderno de notas personal donde guardas informacion que necesitas acceder rapidamente, incluso sin conexion a internet.
En React Native con Expo, tenemos dos opciones principales: AsyncStorage y SQLite. AsyncStorage es como una caja simple donde guardas cosas con etiquetas - perfecta para datos pequenos como preferencias de usuario o tokens. SQLite es como un archivador organizado con carpetas y documentos - ideal para datos estructurados complejos que necesitan consultas avanzadas.
La decision entre uno y otro depende del volumen y complejidad de tus datos. Para menos de 2MB y datos simples, AsyncStorage es suficiente. Para mas datos o relaciones complejas, SQLite es tu mejor opcion.
Como funciona en la practica
Vamos a implementar un sistema de almacenamiento para una app de tareas. Primero, instalaremos las dependencias necesarias. Para AsyncStorage, ya viene incluido en React Native, pero con Expo necesitamos instalar una version especifica.
Paso 1: Instalar dependencias. Abre tu terminal y ejecuta:
npx expo install @react-native-async-storage/async-storage
expo install expo-sqlitePaso 2: Configurar AsyncStorage para guardar el tema de la app (claro/oscuro). Paso 3: Configurar SQLite para guardar las tareas con fecha, prioridad y estado. Paso 4: Implementar sincronizacion entre almacenamiento local y servidor cuando haya conexion.
Codigo en accion
Veamos primero como usar AsyncStorage para guardar preferencias del usuario:
import AsyncStorage from '@react-native-async-storage/async-storage';
// Guardar un valor
const saveUserPreference = async (key, value) => {
try {
await AsyncStorage.setItem(key, JSON.stringify(value));
console.log('Preferencia guardada correctamente');
} catch (error) {
console.error('Error al guardar:', error);
}
};
// Ejemplo de uso
await saveUserPreference('@theme', 'dark');
await saveUserPreference('@notifications', true);
// Leer un valor
const getUserPreference = async (key) => {
try {
const value = await AsyncStorage.getItem(key);
return value != null ? JSON.parse(value) : null;
} catch (error) {
console.error('Error al leer:', error);
return null;
}
};
// Ejemplo de lectura
const theme = await getUserPreference('@theme');
console.log('Tema actual:', theme);Ahora, veamos SQLite para datos mas complejos. Antes teniamos solo AsyncStorage, pero al crecer la app necesitamos mas estructura:
import * as SQLite from 'expo-sqlite';
// Abrir o crear base de datos
const db = SQLite.openDatabase('tasks.db');
// Inicializar tabla
const initDatabase = () => {
db.transaction(tx => {
tx.executeSql(
'CREATE TABLE IF NOT EXISTS tasks (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, completed BOOLEAN, priority INTEGER, created_at DATETIME DEFAULT CURRENT_TIMESTAMP)',
[],
() => console.log('Tabla creada/existe'),
(_, error) => console.error('Error creando tabla:', error)
);
});
};
// Insertar una tarea
const addTask = (title, priority = 1) => {
return new Promise((resolve, reject) => {
db.transaction(tx => {
tx.executeSql(
'INSERT INTO tasks (title, completed, priority) VALUES (?, ?, ?)',
[title, false, priority],
(_, result) => resolve(result.insertId),
(_, error) => reject(error)
);
});
});
};
// Consultar tareas pendientes
const getPendingTasks = () => {
return new Promise((resolve, reject) => {
db.transaction(tx => {
tx.executeSql(
'SELECT * FROM tasks WHERE completed = ? ORDER BY priority DESC, created_at ASC',
[false],
(_, { rows }) => resolve(rows._array),
(_, error) => reject(error)
);
});
});
};
// Ejemplo de uso
await initDatabase();
const taskId = await addTask('Comprar leche', 2);
const pendingTasks = await getPendingTasks();
console.log('Tareas pendientes:', pendingTasks);Errores comunes
1. No manejar errores en operaciones asincronas: Siempre usa try-catch con AsyncStorage y callbacks de error con SQLite. Sin esto, tu app puede crashear silenciosamente.
2. Exceder el limite de AsyncStorage: AsyncStorage tiene limite de ~6MB en iOS y ~10MB en Android. Si necesitas mas, migra a SQLite antes de que los usuarios tengan problemas.
3. No serializar datos complejos: AsyncStorage solo guarda strings. Si intentas guardar objetos directamente, se convertiran a [object Object]. Usa JSON.stringify() y JSON.parse().
4. Bloques de transaccion muy grandes en SQLite: Agrupa operaciones relacionadas en una sola transaccion, pero no metas todo en una. Divide en transacciones logicas.
5. Olvidar cerrar conexiones de base de datos: Con SQLite, aunque Expo maneja algunas cosas, en apps complejas considera cerrar conexiones cuando no las uses.
Checklist de dominio
- Puedo instalar y configurar tanto AsyncStorage como SQLite en un proyecto Expo
- Se cuando usar AsyncStorage (datos simples) vs SQLite (datos complejos)
- Implemento manejo de errores robusto en todas las operaciones de almacenamiento
- Serializo y deserializo datos correctamente para AsyncStorage
- Creo tablas y ejecuto consultas SQL basicas en SQLite
- Manejo transacciones apropiadamente para mantener integridad de datos
- Implemento una estrategia de sincronizacion entre almacenamiento local y servidor remoto
Implementa un sistema de notas con almacenamiento local
Crea una app de notas que permita:
- Crear nuevas notas con titulo y contenido
- Listar todas las notas ordenadas por fecha de creacion
- Marcar notas como favoritas
- Buscar notas por texto en titulo o contenido
- Persistir los datos localmente
Paso 1: Configura un nuevo proyecto Expo o usa uno existente
Paso 2: Instala las dependencias necesarias para AsyncStorage y SQLite
Paso 3: Decide que sistema usar (AsyncStorage o SQLite) basado en los requisitos
Paso 4: Implementa las funciones CRUD para las notas
Paso 5: Crea una interfaz basica con React Native para probar la funcionalidad
Paso 6: Agrega la funcionalidad de busqueda
Paso 7: Implementa la marcacion de favoritos
Paso 8: Prueba que los datos persistan al cerrar y reabrir la app
Pistas- Considera usar SQLite por la necesidad de busqueda y ordenacion
- Para la busqueda, usa la clausula LIKE de SQL o filtra arrays en JavaScript
- Guarda las fechas como timestamps para facilitar el ordenamiento
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.