Learn Rust Coding · Aula

Gerenciando o estado do aplicativo

Armazene e atualize os dados da UI.

Aula 3 de 413 etapas

Gerenciando o estado do aplicativo é uma aula grátis de Learn Rust Coding no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Learn Rust Coding, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Learn Rust Coding inclui 4 aulas no total.

Estado na estrutura do App

No egui, o estado do seu aplicativo é formado por dados comuns de Rust que vivem na estrutura que implementa eframe::App. Não há um armazenamento especial nem um modelo pertencente ao framework.

Os campos contêm tudo: entradas de formulários, seleções, dados carregados e sinalizadores. A cada quadro, update lê e modifica esses campos diretamente por meio de &mut self.

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

Derivando Default

O eframe cria seu aplicativo em uma closure passada para run_native. O padrão mais simples é #[derive(Default)] e a construção com App::default().

Para valores iniciais que não sejam padrão, implemente Default manualmente ou adicione um construtor que receba o CreationContext para configurações como fontes ou persistência.

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

Fonte única da verdade

Como os widgets usam empréstimo &mut dos campos que os respaldam, a estrutura é sempre a fonte única da verdade. Não há um estado de visualização separado para manter sincronizado.

Uma caixa de seleção vinculada a &mut self.enabled reflete e atualiza esse booleano diretamente — leia-o em qualquer outro lugar do mesmo quadro e você verá o valor atual.

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

Adiar modificações

Um problema sutil de empréstimo: muitas vezes você percorre um Vec enquanto deseja remover itens dele. Não é possível modificar o vetor enquanto houver um empréstimo compartilhado ativo.

A solução é registrar a ação pretendida em uma variável local durante o laço e aplicá-la depois que o laço terminar.

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); }

Telas orientadas por enum

Para aplicativos com várias telas, modele a visualização atual como um campo enum. O método update usa uma correspondência sobre ele para decidir o que desenhar.

Isso mantém a navegação explícita e exaustiva — o compilador obriga você a tratar cada tela, eliminando classes inteiras de erros de roteamento.

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),
}

Memória do egui para o estado da interface

Parte do estado diz respeito apenas à interface, não ao seu domínio — seções recolhidas, posições de rolagem e estado de arrasto. O egui armazena isso em ctx.memory, indexado pelo Id do widget.

Você raramente o acessa diretamente, mas ctx.data_mut permite guardar pequenos valores por ID que persistem entre os quadros sem sobrecarregar a estrutura do seu App.

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));

Trabalho em segundo plano com canais

Nunca bloqueie update com operações lentas de E/S — isso congela o laço de 60 quadros por segundo. Crie uma thread e comunique-se por meio de um canal std::sync::mpsc.

O trabalhador envia os resultados de volta; update esvazia o receptor sem bloqueá-lo, usando try_recv a cada quadro. Chame ctx.request_repaint() no trabalhador para que a interface seja redesenhada quando os dados chegarem.

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

Criando o trabalhador

Clone o Context e o remetente para dentro da thread. O clone é barato — internamente, ele é um Arc — e permite que o trabalhador solicite redesenhos.

Mova a propriedade das entradas de trabalho para dentro da closure para satisfazer o verificador de empréstimos e evitar problemas de tempo 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();
});

Persistindo o estado

O eframe pode serializar seu aplicativo entre as execuções. Ative o recurso persistence, derive serde::Serialize / Deserialize e implemente App::save.

Na inicialização, leia o estado salvo de cc.storage no seu construtor, usando os valores padrão como alternativa quando nada estiver armazenado.

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; }
}

Mantendo update eficiente

Como update é executado a cada quadro, evite recalcular dados derivados caros nele. Armazene os resultados em cache nos campos e recalcule-os apenas quando as entradas mudarem.

Um padrão comum é acompanhar um sinalizador dirty definido por Response::changed() e reconstruir os caches no início de update somente quando ele estiver ativo.

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

A propriedade mantém tudo sob controle

O tema recorrente é o seguinte: o egui depende da propriedade de Rust, em vez de frameworks, para gerenciar o estado. Sua estrutura é proprietária dos dados, &mut self concede acesso exclusivo a cada quadro e as threads se comunicam por canais.

Não há assinaturas ocultas nem grafos de callbacks, portanto entender quando e como o estado muda continua sendo algo local e explícito.

Verificação rápida

Como você deve executar uma busca de rede lenta?

Recapitulação

O estado do App consiste em campos comuns na estrutura eframe::App, modificados por meio de &mut self a cada quadro, tornando a estrutura a fonte única da verdade.

Adie modificações durante a iteração, modele as telas com enums, transfira o trabalho lento para threads usando canais e persista os dados com o armazenamento do eframe. Mantenha update eficiente armazenando dados derivados em cache por trás de sinalizadores de alteração. A seguir: empacotamento do seu aplicativo para distribuição.

Grátis para começar

Aprenda Rust com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
39
Aulas
144

Perguntas Frequentes

A aula “Gerenciando o estado do aplicativo” é grátis?

Sim — o texto completo de “Gerenciando o estado do aplicativo” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Learn Rust Coding, atualize para CoddyKit PRO. O curso de Learn Rust Coding inclui 4 aulas no total.

O que vou aprender em “Gerenciando o estado do aplicativo”?

Armazene e atualize os dados da UI. Você pratica Learn Rust Coding com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Learn Rust Coding?

Nenhuma experiência prévia é necessária. Learn Rust Coding no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Gerenciando o estado do aplicativo”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Learn Rust Coding?

Sim. Cada aula de Learn Rust Coding inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Fundamentos de UI em modo imediato
  2. Widgets e layout
  3. Gerenciando o estado do aplicativo
  4. Empacotando um aplicativo de desktop
← Voltar para Learn Rust Coding