Entendendo e aplicando o padrão de estado em Flutter (Parte 1)

Ao desenvolver aplicativos de front -end, geralmente encontramos a idéia de estados: seja um aplicativo, uma tela ou um fluxo específico. Isso adiciona muita informação e reatividade, e acabamos chamando esse processo de “gerenciamento de estado”, mesmo que não entendamos completamente o que é um estado ou como isso afeta nossa aplicação. Neste artigo, examinaremos um problema, uma solução e sua implementação, aprofundando nossa compreensão da gestão do estado. Tópicos Problem Solution Implementation Problem Vamos começar com um exemplo “Na lista de contatos, estamos separando nossa lógica de negócios da interface do usuário, não é legal?!” -Sim, mas vamos pensar sobre isso: o conteúdo da tela mudará dependendo de algum valor? Se sim, quais valores seriam esses? “Nessa lista de contatos e o nome personalizado do usuário que é carregado posteriormente, mas é isso” -Eu, mas haveria algum componente de carregamento ou erro exibido? “Sim, sim. Se estiver carregando, exibimos um esqueleto. Se houver um erro, exibimos um componente de erro com a mensagem de erro e o botão de tentar novamente” … e, portanto, uma tela precisa ouvir algumas variáveis: a lista de contatos, o nome personalizado do usuário, talvez um booleano indicando se está carregando e uma mensagem de erro (que seria indicável). Muito para uma tela simples, não é? Esse cenário é mais comum do que parece. Se um estado é um valor que afeta o fluxo de um sistema, nossa tela de contato – o sistema em questão – tem mais estados do que o necessário. No final, se tudo é um estado, então nada é um estado. O conceito perde sua relevância e apenas adiciona complexidade ao código. Mas o que isso afeta? Nesse cenário, a tela teria que ter vários componentes reativos (ValuelistenableBuilder, ListenableBuilder, Blocbuilder, OBX … Faça a sua escolha), mas ainda podemos imaginar como seria que algo inevitável seria exibido: uma barra de App que exibe o nome personalizado do usuário, um esqueleto que pode ou não ser exibido, uma lista e um componente. Em um dispositivo móvel. Agora entenda que esse comportamento pode ser repetido de maneira semelhante em outras telas, considerando também que o Flutter recarrega a tela atual durante a navegação. Acabamos lidando com 2 problemas principais: muitas coisas que estão sendo renderizadas: Flutter melhorou muito seu desempenho, mas quanto mais coisas são renderizadas em paralelo, mais hardware levará a leitura e a depuração do código: não há uma maneira única de atualizar a tela, qualquer alteração para essas variáveis ​​desencadeará as funções de que outra função pode ser executada. Quem pode nos ajudar? Solução O caminho a seguir ficou mais claro, mas quando me deparei com esses problemas durante o desenvolvimento, o uso do padrão de design do estado se tornou óbvio. É tão recomendável que o Bloc – uma biblioteca de referência no ambiente de vibração – já o use por padrão. Qual é o padrão de estado? Esse formato é baseado em algo que, se você estudou ciência da computação, provavelmente já ouviu falar de: Machine de Estado Finito, que, embora pareça complexo, é como uma porta que só tem o estado de aberto ou fechado e é isso, ou Super Mario: ficando quieto, andando ou pulando. Assim como a programação orientada a objetos é uma simplificação do mundo de hoje, tudo de certa forma também é uma máquina de estado finita. E assim é a sua tela. Este padrão simplificará e criará classes que representam estes estados: se carregar, carregar estado, se errar, errar o estado, se os dados carregarem ….? Estado carregado. Cada um com as informações relevantes para cada estado, principalmente porque não há necessidade de um estado carregado ter uma mensagem de erro que ele não usará. Drawing So let’s make a quick diagram to understand the flow of our screen: we’ll have 3 main states: LoadingState → To display the skeleton ErrorState → To display the error message and the try again button LoadedState → To display the list and the user’s name In particular, I would recommend using a context prefix (eg ContactsLoadingState) so as not to confuse if other screens also use the pattern, but as we only have one context here I’ll keep it that way. Além disso, sugiro também adicionar um estateiro inicial, que seria o chute que inicia o fluxo para que possamos entender as transições. Em relação aos fluxos, podemos seguir algumas regras: o LoadingState pode desencadear o StatedState ou o ErrorState, apenas um ou outro. O FOLTEDEDSTATE pode acionar apenas o carregamento do State (sem exibição de erro em uma tela já carregada). O ErrorState pode acionar apenas LoadingState (se o usuário tentar novamente) InitialState pode acionar apenas o carregamento de carregamento (o primeiro componente exibido é o esqueleto) a partir disso, temos esse fluxo: implementação e é desse fluxo que implementaremos uma solução nesta tela de contato no próximo artigo. Até mais! Fontes:

Fonte

Você pode ter perdido