Learn Rust Coding · Lección

Gestionar el estado de la aplicación

Conserve y actualice los datos de la interfaz

Lección 3 de 413 pasos

Gestionar el estado de la aplicación es una lección gratuita de Learn Rust Coding en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Learn Rust Coding, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Learn Rust Coding incluye 4 lecciones en total.

Estado en la estructura App

En egui, el estado de su aplicación son datos normales de Rust que viven en la estructura que implementa eframe::App. No existe ningún almacén especial ni un modelo administrado por el framework.

Los campos contienen todo: entradas de formularios, selecciones, datos cargados y marcas de estado. En cada frame, update lee y modifica estos campos directamente mediante &mut self.

struct App {
    query: String,
    results: Vec<Item>,
    selected: Option<usize>,
    loading: bool,
}

Derivar Default

eframe crea su aplicación en un cierre que se pasa a run_native. El patrón más sencillo consiste en usar #[derive(Default)] y crearla con App::default().

Para valores iniciales que no sean los predeterminados, implemente Default manualmente o añada un constructor que reciba CreationContext para realizar tareas de configuración, como cargar fuentes o datos persistentes.

impl App {
    fn new(cc: &eframe::CreationContext) -> Self {
        let mut app = Self::default();
        app.dark = cc.egui_ctx.style().visuals.dark_mode;
        app
    }
}

Fuente única de la verdad

Como los widgets toman prestados sus campos subyacentes mediante &mut, la estructura es siempre la única fuente de la verdad. No existe un estado de vista separado que deba mantenerse sincronizado.

Una casilla vinculada a &mut self.enabled refleja y actualiza ese booleano directamente: si lo lee en cualquier otro lugar del mismo frame, verá el valor actual.

ui.checkbox(&mut self.enabled, "Enabled");
if self.enabled {
    ui.label("Feature is on");
}

Posponer las mutaciones

Hay un problema sutil con los préstamos: a menudo se recorre un Vec mientras se desea eliminar elementos de él. No puede modificar el vector mientras exista un préstamo compartido.

La solución consiste en registrar la acción prevista en una variable local durante el bucle y aplicarla después de que este termine.

let mut to_remove = None;
for (i, item) in self.items.iter().enumerate() {
    ui.horizontal(|ui| {
        ui.label(&item.name);
        if ui.button("x").clicked() { to_remove = Some(i); }
    });
}
if let Some(i) = to_remove { self.items.remove(i); }

Pantallas controladas por enums

En aplicaciones con varias pantallas, modele la vista actual como un campo de tipo enum. El método update hace un match sobre él para decidir qué dibujar.

Así, la navegación queda explícita y exhaustiva: el compilador le obliga a gestionar todas las pantallas y elimina toda una clase de errores de enrutamiento.

enum Screen { Home, Settings, About }

match self.screen {
    Screen::Home => self.draw_home(ui),
    Screen::Settings => self.draw_settings(ui),
    Screen::About => self.draw_about(ui),
}

Memoria de egui para el estado de la interfaz

Parte del estado corresponde exclusivamente a la interfaz, no al dominio: secciones contraídas, posiciones de desplazamiento y estado de arrastre. egui lo almacena en ctx.memory, asociado a un Id de widget.

Rara vez tendrá que acceder a ello directamente, pero ctx.data_mut le permite guardar valores pequeños asociados a cada id que persisten entre frames sin recargar la estructura de su aplicación.

let id = egui::Id::new("my_toggle");
let mut open = ctx.data_mut(|d| d.get_temp::<bool>(id).unwrap_or(false));
ui.checkbox(&mut open, "Open");
ctx.data_mut(|d| d.insert_temp(id, open));

Trabajo en segundo plano con canales

Nunca bloquee update con operaciones de E/S lentas: congelaría el bucle de 60 fps. Cree un hilo y comuníquese mediante un canal std::sync::mpsc.

El worker envía los resultados; update vacía el receptor sin bloquear mediante try_recv en cada frame. Llame a ctx.request_repaint() desde el worker para que la interfaz se reactive cuando lleguen datos.

if let Ok(msg) = self.rx.try_recv() {
    self.results = msg;
    self.loading = false;
}

Crear el worker

Clone Context y el sender dentro del hilo. La clonación es económica —internamente es un Arc— y permite que el worker solicite repaints.

Mueva la propiedad de las entradas de trabajo al cierre para satisfacer al borrow checker y evitar problemas de tiempo de vida.

let tx = self.tx.clone();
let ctx = ctx.clone();
std::thread::spawn(move || {
    let data = expensive_load();
    let _ = tx.send(data);
    ctx.request_repaint();
});

Persistencia del estado

eframe puede serializar su aplicación entre ejecuciones. Habilite la característica persistence, derive serde::Serialize / Deserialize e implemente App::save.

Al iniciar, lea el estado guardado desde cc.storage en el constructor y use los valores predeterminados como alternativa cuando no haya nada almacenado.

fn save(&mut self, storage: &mut dyn eframe::Storage) {
    eframe::set_value(storage, eframe::APP_KEY, self);
}
// in new():
if let Some(s) = cc.storage {
    if let Some(app) = eframe::get_value(s, eframe::APP_KEY) { return app; }
}

Mantener update ligero

Como update se ejecuta en cada frame, evite recalcular allí datos derivados costosos. Guarde los resultados en campos y vuelva a calcularlos solo cuando cambien las entradas.

Un patrón habitual consiste en mantener una marca dirty establecida por Response::changed() y reconstruir las cachés al principio de update únicamente cuando esté activa.

if self.dirty {
    self.filtered = self.filter_items();
    self.dirty = false;
}
for item in &self.filtered { ui.label(&item.name); }

La propiedad mantiene la coherencia

El tema recurrente es que egui se apoya en la propiedad de Rust en lugar de en frameworks para gestionar el estado. Su estructura es propietaria de los datos, &mut self concede acceso exclusivo en cada frame y los hilos se comunican mediante canales.

No hay suscripciones ocultas ni grafos de callbacks, por lo que razonar sobre cuándo y cómo cambia el estado sigue siendo algo local y explícito.

Comprobación rápida

¿Cómo debería ejecutar una solicitud de red lenta?

Recapitulación

El estado de la aplicación son campos normales de la estructura eframe::App, modificados mediante &mut self en cada frame, lo que convierte a la estructura en la única fuente de la verdad.

Posponga las mutaciones durante los recorridos, modele las pantallas con enums, delegue el trabajo lento a hilos mediante canales y persista el estado con el almacenamiento de eframe. Mantenga update ligero almacenando en caché los datos derivados mediante marcas dirty. A continuación: empaquetar la aplicación para su distribución.

Gratis para empezar

Aprende Rust con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
39
Lecciones
144

Preguntas frecuentes

¿La lección «Gestionar el estado de la aplicación» es gratis?

Sí — el texto completo de «Gestionar el estado de la aplicación» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Learn Rust Coding, actualiza a CoddyKit PRO. El curso de Learn Rust Coding incluye 4 lecciones en total.

¿Qué aprenderé en «Gestionar el estado de la aplicación»?

Conserve y actualice los datos de la interfaz Practicas Learn Rust Coding con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Learn Rust Coding?

No se requiere experiencia previa. Learn Rust Coding en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Gestionar el estado de la aplicación»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Learn Rust Coding?

Sí. Cada lección de Learn Rust Coding incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Conceptos básicos de la interfaz de usuario en modo inmediato
  2. Widgets y distribución
  3. Gestionar el estado de la aplicación
  4. Empaquetar una aplicación de escritorio
← Volver a Learn Rust Coding