Por várias razões, às vezes o build
método dos meus widgets é chamado novamente.
Eu sei que isso acontece porque um pai atualizou. Mas isso causa efeitos indesejados. Uma situação típica em que causa problemas é quando se usa FutureBuilder
desta maneira:
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: httpCall(),
builder: (context, snapshot) {
// create some layout here
},
);
}
Neste exemplo, se o método de construção fosse chamado novamente, ele acionaria outra solicitação http. O que é indesejável.
Considerando isso, como lidar com a compilação indesejada? Existe alguma maneira de impedir a chamada de compilação?
flutter
flutter-widget
Rémi Rousselet
fonte
fonte
Respostas:
O método de compilação foi projetado de forma a ser puro / sem efeitos colaterais . Isso ocorre porque muitos fatores externos podem acionar uma nova compilação de widget, como:
Class.of(context)
alteração ( padrão)Isso significa que o
build
método não deve acionar uma chamada http ou modificar qualquer estado .Como isso está relacionado à questão?
O problema que você está enfrentando é que seu método de compilação tem efeitos colaterais / não é puro, tornando a chamada de compilação estranha problemática.
Em vez de impedir a chamada de construção, você deve tornar seu método de construção puro, para que possa ser chamado a qualquer momento sem impacto.
No caso do seu exemplo, você transformaria seu widget em uma
StatefulWidget
extração da chamada HTTP para ainitState
suaState
:Também é possível criar um widget capaz de reconstruir sem forçar seus filhos a construir também.
Quando a instância de um widget permanece a mesma; A vibração propositalmente não reconstrói as crianças. Isso implica que você pode armazenar em cache partes da sua árvore de widgets para evitar reconstruções desnecessárias.
A maneira mais fácil é usar
const
construtores de dardo :Graças a essa
const
palavra-chave, a instância deDecoratedBox
permanecerá a mesma, mesmo que a compilação tenha sido chamada centenas de vezes.Mas você pode obter o mesmo resultado manualmente:
Neste exemplo, quando o StreamBuilder for notificado sobre novos valores,
subtree
não será reconstruído, mesmo que o StreamBuilder / Column o faça. Isso acontece porque, graças ao fechamento, a instância deMyWidget
não mudou.Esse padrão é muito usado em animações. Os usos típicos são
AnimatedBuilder
e todas as transições, comoAlignTransition
.Você também pode armazenar
subtree
em um campo da sua classe, embora seja menos recomendado, pois quebra o recurso de recarga a quente.fonte
subtree
em um campo de classe é recarregado a quente?StreamBuilder
enfrentando é que, quando o teclado aparece, a tela muda, então as rotas precisam ser reconstruídas. Então,StreamBuilder
é reconstruído e um novoStreamBuilder
é criado e ele assina ostream
. Quando umStreamBuilder
assina umstream
,snapshot.connectionState
torna-se oConnectionState.waiting
que faz com que meu código retorneCircularProgressIndicator
aesnapshot.connectionState
muda quando há dados, e meu código retorna um widget diferente, o que faz a tela piscar com coisas diferentes.StatefulWidget
, assinar ostream
oninitState()
e definir ocurrentWidget
comsetState()
comostream
envia novos dados, passandocurrentWidget
para obuild()
método Existe uma solução melhor?FutureBuilder
.Você pode impedir chamadas de build indesejadas usando estas
1) Criar classe Statefull filho para uma pequena parte individual da interface do usuário
2) Use Provedor de biblioteca, de modo a usá-lo você pode parar indesejado método de construção chamada
Nestes abaixo chamada de método de construção situação
fonte
Flutter também tem
ValueListenableBuilder<T> class
. Ele permite que você reconstrua apenas alguns dos widgets necessários para o seu propósito e pule os widgets caros.você pode ver os documentos aqui documentos de flutter do ValueListenableBuilder
ou apenas o código de exemplo abaixo:
fonte