simple - what is redux javascript




Por que usar o Redux no Facebook Flux? (6)

Aqui está a explicação simples do Redux over Flux. O Redux não tem um despachante. Ele depende de funções puras chamadas de redutores. Não precisa de um despachante. Cada ação é manipulada por um ou mais redutores para atualizar o armazenamento único. Como os dados são imutáveis, os redutores retornam um novo estado atualizado que atualiza a loja

Para mais informações Flux vs Redux

Eu li essa resposta , reduzindo o clichê , olhei alguns exemplos do GitHub e até tentei redux um pouquinho (todo apps).

Pelo que entendi, as motivações oficiais do redux doc oferecem vantagens em comparação às arquiteturas MVC tradicionais. MAS não fornece uma resposta para a pergunta:

Por que você deveria usar o Redux no Facebook Flux?

Isso é apenas uma questão de estilos de programação: funcional versus não funcional? Ou a questão está nas habilidades / ferramentas de desenvolvimento que se seguem da abordagem de redux? Talvez escalando? Ou testando?

Estou certo se digo que redux é um fluxo para pessoas que vêm de linguagens funcionais?

Para responder a esta pergunta, você pode comparar a complexidade dos pontos de motivação do redux de implementação no fluxo vs redux.

Aqui estão os pontos de motivação das motivações oficiais do redux doc :

  1. Lidando com atualizações otimistas ( pelo que entendi, dificilmente depende do 5º ponto. É difícil implementá-lo no facebook flux? )
  2. Renderização no servidor (o facebook flux também pode fazer isso. Quaisquer benefícios em relação ao redux? )
  3. Buscando dados antes de realizar transições de rota ( Por que isso não pode ser alcançado no fluxo do Facebook? Quais são os benefícios? )
  4. Recarregamento a quente ( é possível com React Hot Reload . Por que precisamos de redux? )
  5. Funcionalidade de desfazer / refazer
  6. Algum outro ponto? Como estado persistente ...


Eu trabalhei bastante tempo com o Flux e agora bastante tempo usando o Redux. Como Dan apontou, as duas arquiteturas não são tão diferentes. A coisa é que o Redux torna as coisas mais simples e limpas. Ensina algumas coisas sobre o Flux. Como, por exemplo, o Flux é um exemplo perfeito de fluxo de dados de uma direção. Separação de interesses em que temos dados, suas manipulações e camadas de visualização separadas. No Redux temos as mesmas coisas, mas também aprendemos sobre imutabilidade e funções puras.


Redux author aqui!

O Redux não é tão diferente do Flux. No geral, tem a mesma arquitetura, mas o Redux é capaz de cortar alguns cantos de complexidade usando composição funcional, onde o Flux usa o registro de retorno de chamada.

Não existe uma diferença fundamental no Redux, mas acho que torna certas abstrações mais fáceis, ou pelo menos possíveis de implementar, que seria difícil ou impossível de implementar no Flux.

Composição Redutor

Tome, por exemplo, paginação. Meu exemplo de Flux + React Router manipula paginação, mas o código para isso é horrível. Uma das razões é terrível porque o Flux torna pouco natural a reutilização de funcionalidades em todas as lojas. Se duas lojas precisarem lidar com a paginação em resposta a diferentes ações, elas precisarão herdar de um armazenamento de base comum (ruim! Você está se travando em um design particular quando usar herança) ou chamar uma função definida externamente de dentro manipulador de eventos, que precisará operar de alguma forma no estado privado da loja Flux. A coisa toda é confusa (embora definitivamente no reino do possível).

Por outro lado, com a paginação Redux é natural graças à composição redutora. Ele é todo reduzido, então você pode escrever uma fábrica de redutores que gera redutores de paginação e então usá-los na sua árvore redutora . A chave do porque é tão fácil é que, no Flux, as lojas são simples, mas no Redux, os redutores podem ser aninhados por meio da composição funcional, assim como os componentes do React podem ser aninhados.

Esse padrão também permite recursos maravilhosos como undo/redo sem código de usuário. Você pode imaginar ligar o Undo / Redo em um aplicativo Flux sendo duas linhas de código? Dificilmente. Com o Redux, é novamente, graças ao padrão de composição do redutor. Eu preciso destacar que não há nada de novo nisso - este é o padrão pioneiro e descrito em detalhes na Elm Architecture, que foi influenciada pelo Flux.

Renderização de Servidores

As pessoas processam bem o servidor com o Flux, mas vendo que temos 20 bibliotecas Flux tentando tornar a renderização do servidor “mais fácil”, talvez o Flux tenha algumas arestas no servidor. A verdade é que o Facebook não faz muito a renderização do servidor, então eles não estão muito preocupados com isso, e contam com o ecossistema para tornar isso mais fácil.

No Flux tradicional, as lojas são singletons. Isso significa que é difícil separar os dados para diferentes solicitações no servidor. Não é impossível, mas é difícil. É por isso que a maioria das bibliotecas Flux (assim como os novos Flux Utils ) agora sugerem que você use classes em vez de singletons, para que você possa instanciar as lojas por solicitação.

Ainda existem os seguintes problemas que você precisa resolver no Flux (seja você mesmo ou com a ajuda da sua biblioteca Flux favorita, como Flummox ou Alt ):

  • Se as lojas são classes, como faço para criá-las e destruí-las com o dispatcher por solicitação? Quando faço para registrar lojas?
  • Como faço para hidratar os dados das lojas e depois reidratá-los no cliente? Preciso implementar métodos especiais para isso?

Admitidamente, os frameworks Flux (não o vanilla Flux) têm soluções para esses problemas, mas eu os acho supercomplicados. Por exemplo, Flummox pede para você implementar serialize() e deserialize() em suas lojas . Alt resolve isso melhor, fornecendo takeSnapshot() que automaticamente serializa seu estado em uma árvore JSON.

O Redux vai mais além: como há apenas uma única loja (gerenciada por muitos redutores), você não precisa de nenhuma API especial para gerenciar a (re) hidratação. Você não precisa “liberar” ou “hidratar” as lojas - há apenas uma única loja, e você pode ler seu estado atual ou criar uma nova loja com um novo estado. Cada solicitação obtém uma instância de loja separada. Leia mais sobre a renderização do servidor com o Redux.

Novamente, este é um caso de algo possível tanto no Flux quanto no Redux, mas as bibliotecas Flux resolvem esse problema introduzindo uma tonelada de API e convenções, e o Redux nem precisa resolvê-lo porque ele não tem esse problema no primeiro lugar graças à simplicidade conceitual.

Experiência do desenvolvedor

Eu realmente não pretendia que o Redux se tornasse uma popular biblioteca Flux - escrevi enquanto estava trabalhando na minha palestra na ReactEurope sobre recarga quente com viagens no tempo . Eu tinha um objetivo principal: tornar possível alterar o código do redutor rapidamente ou até mesmo "mudar o passado", riscando as ações, e ver o estado sendo recalculado.

Eu não vi uma única biblioteca Flux que seja capaz de fazer isso. O React Hot Loader também não permite que você faça isso - na verdade, ele quebra se você editar as lojas Flux porque ele não sabe o que fazer com elas.

Quando o Redux precisa recarregar o código do redutor, ele chama replaceReducer() e o aplicativo é executado com o novo código. No Flux, dados e funções estão emaranhados nas lojas Flux, então você não pode “simplesmente substituir as funções”. Além disso, você teria que de alguma forma registrar novamente as novas versões com o Dispatcher - algo que o Redux nem tem.

Ecossistema

O Redux tem um ecossistema rico e de rápido crescimento . Isso porque fornece alguns pontos de extensão, como middleware . Ele foi projetado com casos de uso como logging , suporte para Promises , Observables , routing , verificações de desenvolvimento de imutabilidade , persistence , etc., em mente. Nem todos eles serão úteis, mas é bom ter acesso a um conjunto de ferramentas que podem ser facilmente combinadas para funcionar em conjunto.

Simplicidade

O Redux preserva todos os benefícios do Flux (gravação e reprodução de ações, fluxo de dados unidirecional, mutações dependentes) e adiciona novos benefícios (fácil desfazer-refazer, hot recarregamento) sem introduzir o Dispatcher e o registro da loja.

Mantê-lo simples é importante porque o mantém saudável enquanto você implementa abstrações de alto nível.

Diferentemente da maioria das bibliotecas Flux, a superfície da Redux API é pequena. Se você remover os avisos do desenvolvedor, os comentários e as verificações de integridade, serão 99 linhas . Não há código assíncrono complicado para depurar.

Você pode realmente ler e entender todo o Redux.

Veja também minha resposta nas desvantagens do uso do Redux comparado ao Flux .


Você pode ser melhor começar lendo este post de Dan Abramov, onde ele discute várias implementações do Flux e seus trade-offs no momento em que ele estava escrevendo redux: The Evolution of Flux Frameworks

Em segundo lugar, essa página de motivações que você liga não discute realmente as motivações do Redux, mas sim as motivações por trás do Flux (e do React). Os Três Princípios são mais específicos do Redux, embora ainda não lidem com as diferenças de implementação da arquitetura padrão do Flux.

Basicamente, o Flux tem várias lojas que calculam a mudança de estado em resposta a interações de UI / API com componentes e transmitem essas mudanças como eventos aos quais os componentes podem se inscrever. No Redux, existe apenas uma loja que todo componente assina. A IMO sente que pelo menos o Redux simplifica e unifica o fluxo de dados unificando (ou reduzindo, como diria Redux) o fluxo de dados de volta para os componentes - enquanto o Flux se concentra em unificar o outro lado do fluxo de dados - modelo.


No Quora, alguém diz :

Primeiro de tudo, é totalmente possível escrever aplicativos com o React without Flux.

Também este diagrama visual que eu criei para mostrar uma visão rápida de ambos, provavelmente uma resposta rápida para as pessoas que não querem ler a explicação completa:

Mas se você ainda está interessado em saber mais, continue a ler.

Eu acredito que você deveria começar com o puro React, então aprender Redux e Flux. Depois de ter alguma experiência REAL com o React, você verá se o Redux é útil ou não.

Talvez você sinta que o Redux é exatamente para o seu aplicativo e talvez você descubra que o Redux está tentando resolver um problema que você não está experimentando.

Se você começar diretamente com o Redux, você pode acabar com código superprojetado, código mais difícil de manter e com ainda mais bugs e sem o Redux.

Do Redux docs :

Motivação
Como os requisitos para aplicativos de página única do JavaScript se tornaram cada vez mais complicados, nosso código deve gerenciar mais estados do que nunca. Esse estado pode incluir respostas do servidor e dados armazenados em cache, bem como dados criados localmente que ainda não foram persistidos no servidor. O estado da interface do usuário também está aumentando em complexidade, já que precisamos gerenciar rotas ativas, guias selecionadas, spinners, controles de paginação e assim por diante.

Gerenciar esse estado em constante mudança é difícil. Se um modelo puder atualizar outro modelo, uma visualização poderá atualizar um modelo, que atualizará outro modelo, e isso, por sua vez, poderá fazer com que outra visão seja atualizada. Em algum momento, você não entende mais o que acontece no seu aplicativo, pois perdeu o controle sobre quando, por que e como está. Quando um sistema é opaco e não determinístico, é difícil reproduzir erros ou adicionar novos recursos.

Como se isso não fosse ruim o suficiente, considere os novos requisitos se tornando comuns no desenvolvimento de produtos front-end. Como desenvolvedores, espera-se que lidemos com atualizações otimistas, renderização do lado do servidor, buscando dados antes de realizar transições de rotas e assim por diante. Nós nos encontramos tentando administrar uma complexidade com a qual nunca tivemos que lidar antes, e inevitavelmente fazemos a pergunta: é hora de desistir? A resposta é não.

Essa complexidade é difícil de lidar, pois estamos misturando dois conceitos que são muito difíceis para a mente humana pensar: mutação e assincronia. Eu os chamo de Mentos e Coca-Cola. Ambos podem ser ótimos quando separados, mas juntos eles criam uma bagunça. Bibliotecas como o React tentam resolver esse problema na camada de visualização removendo tanto o assíncrono quanto a manipulação direta do DOM. No entanto, gerenciar o estado de seus dados é deixado para você. É aqui que entra o Redux.

Seguindo os passos do Flux, CQRS e Event Sourcing, o Redux tenta tornar as mutações de estado previsíveis, impondo certas restrições sobre como e quando as atualizações podem acontecer. Essas restrições são refletidas nos três princípios do Redux.

Também do Redux docs :

Conceitos Básicos
O próprio Redux é muito simples.

Imagine que o estado do seu aplicativo é descrito como um objeto simples. Por exemplo, o estado de um aplicativo todo pode ter esta aparência:

{
  todos: [{
    text: 'Eat food',
    completed: true
  }, {
    text: 'Exercise',
    completed: false
  }],
  visibilityFilter: 'SHOW_COMPLETED'
}

Este objeto é como um "modelo", exceto que não há setters. Isso é para que diferentes partes do código não possam alterar o estado arbitrariamente, causando erros difíceis de reproduzir.

Para mudar algo no estado, você precisa despachar uma ação. Uma ação é um objeto JavaScript simples (observe como não introduzimos nenhuma mágica?) Que descreva o que aconteceu. Aqui estão algumas ações de exemplo:

{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }

Garantir que todas as alterações sejam descritas como uma ação nos permite ter uma compreensão clara do que está acontecendo no aplicativo. Se algo mudou, sabemos porque mudou. Ações são como migalhas de pão do que aconteceu. Finalmente, para amarrar estados e ações juntos, escrevemos uma função chamada redutor. Mais uma vez, nada de magia sobre isso - é apenas uma função que toma estado e ação como argumentos, e retorna o próximo estado do aplicativo. Seria difícil escrever tal função para um aplicativo grande, por isso escrevemos funções menores gerenciando partes do estado:

function visibilityFilter(state = 'SHOW_ALL', action) {
  if (action.type === 'SET_VISIBILITY_FILTER') {
    return action.filter;
  } else {
    return state;
  }
}

function todos(state = [], action) {
  switch (action.type) {
  case 'ADD_TODO':
    return state.concat([{ text: action.text, completed: false }]);
  case 'TOGGLE_TODO':
    return state.map((todo, index) =>
      action.index === index ?
        { text: todo.text, completed: !todo.completed } :
        todo
   )
  default:
    return state;
  }
}

E nós escrevemos outro redutor que gerencia o estado completo do nosso aplicativo chamando esses dois redutores para as chaves de estado correspondentes:

function todoApp(state = {}, action) {
  return {
    todos: todos(state.todos, action),
    visibilityFilter: visibilityFilter(state.visibilityFilter, action)
  };
}

Esta é basicamente a ideia do Redux. Note que não usamos nenhuma API do Redux. Ele vem com alguns utilitários para facilitar esse padrão, mas a idéia principal é que você descreva como seu estado é atualizado ao longo do tempo em resposta a objetos de ação, e 90% do código que você escreve é ​​simplesmente JavaScript, sem uso do Redux. em si, suas APIs ou qualquer mágica.





redux