Gerenciando o estado do aplicativo
Armazene e atualize os dados da UI.
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.
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
- Fundamentos de UI em modo imediato
- Widgets e layout
- Gerenciando o estado do aplicativo
- Empacotando um aplicativo de desktop