Stateless, Stateful, Inherited e Proxy | Widget
- Stateless, Stateful, Inherited e Proxy | Widget
Diferença entre StatelessWidget, StatefulWidget, InheritedWidget e ProxyWidget
1. StatelessWidget
-
O que é? Um widget imutável que não mantém estado interno. Sua aparência depende apenas dos dados recebidos via construtor.
-
Quando usar? Quando seu widget não precisa guardar informações que mudam com o tempo, como botões simples, textos estáticos, ícones, etc.
-
Funcionamento: Toda vez que precisa atualizar, o Flutter chama o método
buildpara reconstruir o widget. -
Exemplo básico:
class MeuTexto extends StatelessWidget {
final String texto;
MeuTexto(this.texto);
Widget build(BuildContext context) {
return Text(texto);
}
}
2. StatefulWidget
-
O que é? Widget que mantém um objeto State associado, onde você pode guardar dados que mudam durante o tempo de vida do widget.
-
Quando usar? Quando seu widget precisa reagir a mudanças internas, como cliques, animações, formulários, carregamento de dados, etc.
-
Funcionamento: O
StatefulWidgetem si é imutável, mas oStatepode mudar. Ao alterar o estado, você chamasetState(), que pede uma reconstrução chamando obuild. -
Exemplo básico:
class Contador extends StatefulWidget {
_ContadorState createState() => _ContadorState();
}
class _ContadorState extends State<Contador> {
int _contador = 0;
void _incrementar() {
setState(() {
_contador++;
});
}
Widget build(BuildContext context) {
return Column(
children: [
Text('Contador: $_contador'),
ElevatedButton(onPressed: _incrementar, child: Text('Incrementar')),
],
);
}
}
3. InheritedWidget
-
O que é? Widget que fornece dados para seus widgets filhos na árvore, permitindo que eles acessem e reajam a mudanças nesses dados sem precisar passar propriedades manualmente para todos.
-
Quando usar? Quando você precisa compartilhar informações amplamente (tema, idioma, dados do usuário) e quer que a atualização desses dados provoque reconstrução automática dos widgets dependentes.
-
Funcionamento:
- Você cria uma classe que estende
InheritedWidgete define os dados que quer compartilhar. - Os widgets filhos acessam esses dados usando
BuildContext.dependOnInheritedWidgetOfExactType(). - Quando os dados mudam, o
InheritedWidgetnotifica os dependentes para reconstruírem.
- Você cria uma classe que estende
-
Exemplo simples:
class MeuInheritedWidget extends InheritedWidget {
final int contador;
MeuInheritedWidget({required this.contador, required Widget child}) : super(child: child);
bool updateShouldNotify(MeuInheritedWidget oldWidget) {
return contador != oldWidget.contador;
}
static MeuInheritedWidget? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<MeuInheritedWidget>();
}
}
No widget filho, você pode usar:
final inherited = MeuInheritedWidget.of(context);
print(inherited?.contador);
4. ProxyWidget
-
O que é? Um widget que atua como intermediário, modificando ou passando informações para seus filhos, mas que não guarda estado próprio.
-
Quando usar? Geralmente usado para criar widgets que alteram o comportamento ou fornecem dados contextuais para a árvore abaixo deles.
-
Exemplos reais:
InheritedWidgeté um tipo deProxyWidget.- Widgets como
MediaQuery,Theme, que modificam ou fornecem dados para seus descendentes.
-
Por que é importante? Porque permite criar padrões onde dados/contexto fluem na árvore de widgets, e mudanças podem ser propagadas sem reescrever toda a estrutura.
Resumo da relação entre eles
| Widget | Mantém estado? | Compartilha dados com filhos? | Exemplo de uso |
|---|---|---|---|
| StatelessWidget | Não | Não | Texto, ícones estáticos |
| StatefulWidget | Sim | Não | Contadores, animações, formulários |
| InheritedWidget | Não (mas compartilha dados) | Sim | Temas, localização, dados globais |
| ProxyWidget | Não | Sim | Widgets que modificam contexto |