O que é Flux
Se você já viu algo sobre React, já brincou ou pelo menos acessou a sua documentação, deve ter se deparado com um cara chamado Flux. E se você, assim como eu, ficou um pouco confuso com a ideia, esse post vai descomplicar as coisas para você.
O Flux (prefiro chamar assim) é uma arquitetura usada pelo Facebook, que junto com o framework React é usado para construir aplicações web no client-side que trabalhem de forma reativa. Basicamente uma forma de fluxo unidirecional de dados entre eventos e ouvintes.
Caso você ainda não tenha noção do que é ou de como desenvolver com React, eu indico ler essa sequência de posts:
- Introdução sobre React: https://bit.ly/guia-react
- O que é React e como trabalhar com JSX: https://bit.ly/guia-react-pt1
- Virtual DOM e Criação de Componentes: https://bit.ly/guia-react-pt2
- Estados e propriedades de um Componente: https://bit.ly/guia-react-pt3
O conteúdo é ótimo e em português.
Continuando…
Por que parece complicado?
O nome Flux por si já é algo complicado. Ele faz parecer que Flux é como um framework que você precisa carregar pra começar a usar. Porém, Flux não é nada disso. Na verdade o que o Facebook fez foi: pegar uma coisa chamada fluxo de dados unidirecional, separar em partes, adicionar um cara chamado Dispatcher e chamar isso tudo de Flux.
Então você não precisa se preocupar muito quanto a isso. Flux é um modelo e não uma coisa.
Outra coisa que ajuda a dar uma travada, é que no primeiro contato com Flux nosso cérebro não entende o seu conceito e funcionamento, pois queremos compará-lo a outros modelos que já conhecemos como MVC, MVM e etc. Mas acredite, essa não é a melhor maneira. A primeira “regra” aqui é não comparar. Não tente fazer analogias ou algo do tipo agora, isso só vai tornar as coisas mais complicadas.
Então vamos ter a mente aberta e entender como o Flux funciona.
Obs: Precisei colocar as imagens dos scripts no meu post, pois o WordPress estava interpretando minhas tag como html. Desculpem…
1. O Dispatcher
Flux é inicialmente dividido em 3 partes:
- Dispatcher
- View
- Store
O Dispatcher é como uma central da sua aplicação. Uma central responsável por registrar callbacks e emitir eventos. Por ser uma central, fica claro que deve haver apenas um único Dispatcher para toda sua aplicação. Para instanciá-lo você vai precisar usar a lib Dispatcher.js do Facebook.
Esse é o único código de terceiro que você irá precisar pra rodar sua aplicação Flux.
Mas lembre-se: isso é somente uma lib para fazer Dispatchers, e não o Flux. Como dito antes, não existe algo como uma biblioteca Flux, pois Flux é só uma arquitetura de fluxo.
Para instanciar o Dispatcher é simples:
2. Nossa view faz um Dispatch
A view nada mais é do que um componente React.
Vamos imaginar que nosso app é uma clássica ToDo List.
Nela nosso usuário digita a tarefa e clica em salvar.
Nossa view seria assim:
Quando o usuário clicar em Salvar, nossa view faz o dispatch de um evento específico, através do método AppDispatcher.dispatch:
O método dispatch recebe um objeto como argumento. Nele nós temos os parametros type e data.
Nosso dispatch deve indicar qual evento estamos emitindo, e fazemos isso através do type. Também passamos a informação que queremos salvar através do data.
3. A Store responde o evento do dispatch
Store é o nome que o Facebook decidiu dar para um objeto JavaScript específico, responsável por saber quais são os dados que sua view precisa consumir; e quando e como atualizar a mesma.
No nosso exemplo precisamos de uma lista para salvar nossas tarefas e deletar as mesmas quando nossa view pedir. Vamos chamá-la de TaskStore.
NOTA: _Como você deve ter notado, temos uma variável chamada tasks fora da nossa TaskStore. Essa é somente uma forma de deixar a variável que contém nossas tasks, privada, de forma que a view precise chamar TaskStore.getAll() para ter a lista de tasks.
Na TaskStore o dispatcher precisa registrar um callback para cada evento específico. No Flux isso acontece através do método register da biblioteca Dispatcher:
Normalmente você encontrará esse registro sendo executado dentro de um método da store. Por exemplo:
Essa é a forma como Flux faz o dispatch de callbacks. Cada payload contém um evento com seu tipo e dados, no nosso caso type e data.
Uma estrutura de switch decide o que fazer com essa ação de acordo com o type.
Aqui mudamos nosso array inicial, adicionando a ele uma tarefa.
4. A Store emite um evento quando finaliza a mudança
Como dito, nossa Store é a única responsável por saber quando e como atualizar a nossa View. Sendo assim ela deve avisar quando concluir a ação da nossa View.
Você pode usar a lib que achar melhor para emitir eventos. Uma bem simples é a MicroEvent.js.
Para nosso exemplo eu prefiro usar a EventEmitter do Nodejs, pois com certeza vai se deparar com ela em quase todos os códigos de Flux open source por aí.
Pra instanciá-la é bem fácil:
Você pode ler mais sobre ela aqui.
Além disso precisamos usar o Object.assign() do JavaScript para copiar as propriedades do EventEmitter para nossa TaskStore.
Como ele só esta presente no ES6, vamos usar um polyfill maroto aqui pra fazer a coisa funcionar bonitinha. Se chama object-assign e você aprende mais sobre ele aqui.
Agora com nossa lib de EventEmitter em mãos vamos adicionar à nossa TaskStore os métodos responsáveis por adicionar ouvintes, remover ouvintes e é claro emitir eventos.
Lembra de quando registramos uma ação de adicionar item para o dispatch ‘novo-item’? Então, nossa Store precisa emitir um evento dizendo que essa ação acabou e que nossa View deve se atualizar
NOTA: Somente sua Store faz os registros de callbacks do dispatcher. Sua View nunca deve realiza um AppDispatcher.
Sobre Stores e sua finalidade
Deve haver uma Store para cada propósito de uma parte da sua aplicação.
Isso é um pouco complicado, então vou tentar ser mais claro: Se em sua aplicação você tem um cadastro de funcionários e um cadastro de clientes, você precisa ter uma store para funcionários e uma para os clientes. Ok?
5. A View escuta o evento da Store e atualiza
Nossa View agora precisa escutar o evento da TaskStore para saber que é hora de se atualizar alterando seu estado.
Fazemos isso ouvindo a TaskStore quando o componente for “montado”.
Para que nossa View se atualize devemos utilizar o estado (this.state) do nosso componente, dentro do nosso método render. Dessa forma todas as vezes em que o estado do nosso componente for alterado, nossa view fará um re-render.
No nosso exemplo, pra listar as tasks ficaria assim:
E então por último remova o ouvinte quando nosso componente for “desmontado”
NOTA: Nunca se esqueça de remover todos os ouvintes da sua view/componente quando ela for desmontada
Se você não sabe como funciona o lifecycle de um componente, recomendo dar uma lida na documentação do React.
E Pronto!
Isso é o básico de como funciona o Flux. Claro que esse não foi nenhum tutorial, somente uma explicação de como é o funcionamento. Mas espero ter ajudado um pouco.
Aqui está um exemplo de aplicação com Flux e React desenvolvida pelo Facebook.
Qualquer dúvida, críticas, sugestões ou agradecimentos coloquem aí nos comentários.
Valeu gente!!!
Esse post foi originalmente publicado em macgyvermartins.com.br