Qual é a maneira correta de usar um InheritedWidget? Até agora eu entendi que isso dá a você a chance de propagar dados na árvore de widgets. Em extremo, se você colocar é como RootWidget, ele estará acessível de todos os Widgets na árvore em todas as rotas, o que é bom porque de alguma forma eu tenho que tornar meu ViewModel / Model acessível para meus Widgets sem ter que recorrer a globais ou Singletons.
MAS InheritedWidget é imutável, então como posso atualizá-lo? E mais importante, como meus Stateful Widgets são acionados para reconstruir suas subárvores?
Infelizmente, a documentação aqui não é muito clara e após discussão com muitos ninguém parece realmente saber qual a maneira correta de usá-la.
Eu adicionei uma citação de Brian Egan:
Sim, vejo isso como uma forma de propagar dados na árvore. O que acho confuso nos documentos da API:
"Widgets herdados, quando referenciados dessa forma, farão com que o consumidor reconstrua quando o próprio widget herdado mudar de estado."
Quando li isso pela primeira vez, pensei:
Eu poderia colocar alguns dados no InheritedWidget e transformá-lo mais tarde. Quando essa mutação acontecer, ele irá reconstruir todos os Widgets que fazem referência ao meu InheritedWidget. O que eu encontrei:
Para alterar o estado de um InheritedWidget, você precisa envolvê-lo em um StatefulWidget. Então, você realmente altera o estado do StatefulWidget e passa esses dados para o InheritedWidget, que passa os dados para todos os seus filhos. No entanto, nesse caso, parece reconstruir a árvore inteira sob o StatefulWidget, não apenas os Widgets que fazem referência ao InheritedWidget. Isso é correto? Ou ele de alguma forma saberá como ignorar os Widgets que fazem referência ao InheritedWidget se updateShouldNotify retornar falso?
fonte
MyInherited.of(context)
.updateShouldNotify
teste sempre se refere à mesmaMyInheritedState
instância, ele não retornará semprefalse
? Certamente obuild
método deMyInheritedState
criar novas_MyInherited
instâncias, mas odata
campo sempre faz referência athis
não? Estou tendo problemas ... Funciona se eu apenas codificartrue
.TL; DR
Não use computação pesada dentro do método updateShouldNotify e use const em vez de new ao criar um widget
Em primeiro lugar, devemos entender o que são objetos Widget, Elemento e Render.
Agora estamos prontos para mergulhar no método inheritFromWidgetOfExactType de InheritedWidget e BuildContext .
Como exemplo, recomendo que consideremos este exemplo da documentação do Flutter sobre InheritedWidget:
InheritedWidget - apenas um widget que implementa em nosso caso um método importante - updateShouldNotify . updateShouldNotify - uma função que aceita um parâmetro oldWidget e retorna um valor booleano: verdadeiro ou falso.
Como qualquer widget, InheritedWidget tem um objeto Element correspondente. É InheritedElement . InheritedElement chama updateShouldNotify no widget toda vez que construímos um novo widget (chame setState em um ancestral). Quando updateShouldNotify retorna true, InheritedElement itera por meio de dependências (?) E chama o método didChangeDependencies nele.
Onde InheritedElement obtém dependências ? Aqui devemos olhar para o método inheritFromWidgetOfExactType .
inheritFromWidgetOfExactType - Este método definido em BuildContext e cada Elemento implementa a interface BuildContext (Element == BuildContext). Portanto, cada elemento tem esse método.
Vamos dar uma olhada no código de inheritFromWidgetOfExactType:
Aqui, tentamos encontrar um ancestral em _inheritedWidgets mapeado por tipo. Se o ancestral for encontrado, então chamamos de inheritFromElement .
O código para inheritFromElement :
Portanto, agora sabemos de onde InheritedElement obtém suas dependências.
Agora vamos examinar o método didChangeDependencies . Cada elemento tem este método:
Como podemos ver este método apenas marca um elemento como sujo e este elemento deve ser reconstruído no próximo quadro. Reconstruir significa construir o método de chamada no elemento de widget correspondente.
Mas e quanto a "Reconstruções de subárvore inteira quando eu reconstruo InheritedWidget?". Aqui devemos lembrar que os Widgets são imutáveis e se você criar um novo widget, o Flutter reconstruirá a subárvore. Como podemos arranjá-lo?
fonte
Dos documentos :
Como o OP observou, uma
InheritedWidget
instância não muda ... mas pode ser substituída por uma nova instância no mesmo local na árvore de widgets. Quando isso acontecer, é possível que os widgets registrados precisem ser reconstruídos. OInheritedWidget.updateShouldNotify
método faz essa determinação. (Veja: docs )Então, como uma instância pode ser substituída? Uma
InheritedWidget
instância pode ser contida por umStatefulWidget
, que pode substituir uma instância antiga por uma nova instância.fonte
InheritedWidget gerencia dados centralizados do aplicativo e os passa para o filho, como podemos armazenar aqui a contagem do carrinho conforme explicado aqui :
fonte