Proyecto: App de Notas
Este proyecto integra todos los conceptos del curso en una app funcional: navegación con React Navigation (lista de notas + pantalla de detalle/edición), estado global con Zustand para las notas en memoria, persistencia con AsyncStorage para que las notas sobrevivan al cerrar la app, FlatList para mostrar la lista eficientemente, y animaciones de entrada con Reanimated para una experiencia pulida.
El proyecto te enseña a estructurar una app React Native real: separar la lógica en custom hooks y stores de Zustand, crear componentes reutilizables para las tarjetas de notas, manejar el teclado en iOS/Android (KeyboardAvoidingView), y hacer el texto editable inline. Estos patrones son los mismos que usarías en apps de producción. Una vez terminado, tendrás una base sólida para construir tu propia app mobile.
// store/notasStore.js
import { create } from "zustand";
import { persist, createJSONStorage } from "zustand/middleware";
import AsyncStorage from "@react-native-async-storage/async-storage";
export const useNotasStore = create(
persist(
(set, get) => ({
notas: [],
agregar: (titulo, contenido) => set(state => ({
notas: [
...state.notas,
{ id: Date.now(), titulo, contenido, fecha: new Date().toISOString() }
]
})),
eliminar: (id) => set(state => ({
notas: state.notas.filter(n => n.id !== id)
})),
buscar: (query) => get().notas.filter(n =>
n.titulo.toLowerCase().includes(query.toLowerCase())
),
}),
{ name: "notas", storage: createJSONStorage(() => AsyncStorage) }
)
);
// screens/ListaNotas.jsx
export function ListaNotas({ navigation }) {
const { notas, eliminar } = useNotasStore();
const [busqueda, setBusqueda] = useState("");
const notasFiltradas = notas.filter(n =>
n.titulo.toLowerCase().includes(busqueda.toLowerCase())
);
return (
<View style={styles.container}>
<TextInput
placeholder="Buscar notas..."
value={busqueda}
onChangeText={setBusqueda}
style={styles.buscador}
/>
<FlatList
data={notasFiltradas}
keyExtractor={n => String(n.id)}
renderItem={({ item }) => (
<TouchableOpacity
style={styles.nota}
onPress={() => navigation.navigate("EditarNota", { id: item.id })}
onLongPress={() => eliminar(item.id)}
>
<Text style={styles.tituloNota}>{item.titulo}</Text>
<Text style={styles.fecha}>{new Date(item.fecha).toLocaleDateString()}</Text>
</TouchableOpacity>
)}
/>
<TouchableOpacity
style={styles.fab}
onPress={() => navigation.navigate("NuevaNota")}
>
<Text style={styles.fabTexto}>+</Text>
</TouchableOpacity>
</View>
);
}
Practica esta lección
Resuelve los ejercicios del curso de React Native en la app, gratis y con corrección automática.
Empezar a practicar