3. Flutter: Gerenciador de Estado: setState()
Iremos falar na principal gerencia de estado do Flutter e explicar uma forma inteligente de aplicá-lo

Para se trabalhar com o setState()
nós precisamos de um componente Stateful, pois este componente irá guardar o estado (tudo aquilo que iremos atualizar) para nosso aplicativo.
Vamos criar um aplicativo simples para começar a entender setState():
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
routes: {'/setState': (_) => SetState()});
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("FlutterBrasil"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: () {
Navigator.of(context).pushNamed('/setState');
},
child: Text("Ir para SetState"),
)
],
),
),
);
}
}
class SetState extends StatefulWidget {
@override
_MySetState createState() => _MySetState();
}
class _MySetState extends State {
String nome = "Flutter";
@override
Widget build(BuildContext context) {
print('build');
return Scaffold(
appBar: AppBar(
title: Text("FlutterBrasil"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(nome),
RaisedButton(
onPressed: () {
setState(() {
nome = "Brasil";
});
},
child: Text("alterar nome"),
)
],
),
),
);
}
}
Basicamente, criamos um app em que na primeira tela MyHomePage()
tem um botão que nos leva a segunda tela SetState()
que tem um Text('Flutter')
que é alterado quando se clica no RaisedButton()
e para isso é utilizado o setState().
Toda vez que se chama o setState()
é feito a reconstrução de tudo que está em Widget build (BuildContext context), por exemplo, no código acima, toda vez que você clica no "alterar nome" é refeito a tela SetState() (segunda tela).
Para outras linguagens, isso pode ser um grande problema, mas para o Flutter, por ter uma boa performace, veja aqui o por que, não irá ter tanto problema em uma aplicação muito simples.
Como "resolver" esse rebuild?
Modificador const
Para diminuir a reconstrução de widgets, basta colocar no widget que você não quer que seja reconstruído o const
, como no título da página, em textos que não serão alterados, entre outros:
appBar: AppBar(
title: const Text("FlutterBrasil"),
),
Então, quando você chamar o setState(),
não irá reconstrui-lo.
Criando outro Widget
Mas há também outra alternativa, criando outro componente.
Criaremos outra classe Stateful chamada SetStateComponent()
onde iremos colocar somente o conteúdo que queremos que seja atualizado:
class SetStateComponent extends StatefulWidget {
@override
_MySetStateComponent createState() => _MySetStateComponent();
}
class _MySetStateComponent extends State {
String nome = "Flutter";
@override
Widget build(BuildContext context) {
print('buildComponent');
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(nome),
RaisedButton(
onPressed: () {
setState(() {
nome = "Brasil";
});
},
child: Text("alterar nome"),
)
],
);
}
}
Após, iremos modificar a nossa classe SetState()
para Stateless e chamar a nova classe criada SetStateComponent():
class SetState extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('build');
return Scaffold(
appBar: AppBar(
title: const Text("FlutterBrasil"),
),
body: SetStateComponent(),
);
}
}
Desta forma, eu posso controlar os componentes que serão atualizados.
Código Completo:
Clique aqui e veja aqui este código em funcionamento.