Por que usar o Redux sobre o Facebook Flux? [fechadas]

1126

Eu li essa resposta , reduzindo o padrão , olhei para alguns exemplos do GitHub e até tentei reduxar um pouco (todos os aplicativos).

Pelo que entendi, as motivações oficiais de documentos redux fornecem profissionais comparando com as arquiteturas MVC tradicionais. MAS não fornece uma resposta para a pergunta:

Por que você deve usar o Redux sobre o 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 seguem a abordagem redux? Talvez escalando? Ou testando?

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

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

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

  1. Lidar com atualizações otimistas ( como eu entendo, dificilmente depende do quinto ponto. É difícil implementá-lo no fluxo do facebook? )
  2. Renderização no servidor (o fluxo do facebook também pode fazer isso. Algum benefício em comparação ao redux? )
  3. Buscando dados antes de realizar transições de rota ( por que não podem ser alcançados no fluxo do facebook? Quais são os benefícios? )
  4. Recarga a quente ( é possível com o React Hot Reload . Por que precisamos de redux? )
  5. Desfazer / Refazer funcionalidade
  6. Algum outro ponto? Como estado persistente ...
VB_
fonte
73
Redux é uma implementação do "Facebook Flux". O fluxo não é uma biblioteca ou estrutura. É simplesmente uma arquitetura recomendada para aplicativos da web. Não vejo como você pode comparar uma implementação concreta com o conceito abstrato que a motivou. A implementação real do Facebook de uma arquitetura Flux é o Relay e a versão de código aberto ainda está nos estágios iniciais. facebook.github.io/relay
Charlie Martin
2
@CharlieMartin Por FB Flux Eu uso aplicativos como este github.com/facebook/flux/tree/master/examples . Meu projeto atual está escrito no FB Flux (devido ao FB Flux). Se você quiser, pode pensar em arquitetura Redux sobre arquitetura FB Flux.
VB_
2
Eu entendo agora. Você quer comparar exemplo de implementação Flux do Facebook com a implementação Flux do Redux
Charlie Martin
13
O relé não é uma implementação do Flux - o Relay / GraphQL está mais preocupado com o gerenciamento de busca / consulta de dados com o servidor, enquanto o Flux está principalmente preocupado com a estruturação do fluxo de dados entre os modelos de dados do lado do cliente e os componentes de exibição. No entanto, há alguma sobreposição: no Facebook, temos aplicativos criados inteiramente usando o Flux, usando o Relay ou ambos. Um padrão que vemos emergente é deixar Relé gerenciar a maior parte do fluxo de dados para uma aplicação, mas usando lojas Flux no lado de lidar com um subconjunto de estado do aplicativo
Hal

Respostas:

1958

Autor Redux aqui!

Redux não é isso diferente de Flux. No geral, possui a mesma arquitetura, mas o Redux é capaz de reduzir alguns aspectos da complexidade usando a composição funcional, onde o Flux usa o registro de retorno de chamada.

Não há uma diferença fundamental no Redux, mas acho que isso torna algumas abstrações mais fáceis, ou pelo menos possíveis de implementar, que seriam difíceis ou impossíveis de implementar no Flux.

Composição do redutor

Tome, por exemplo, paginação. Meu exemplo do Flux + React Router lida com paginação, mas o código para isso é horrível. Uma das razões pelas quais é horrível é que o Flux torna natural reutilizar a funcionalidade nas lojas. Se duas lojas precisarem lidar com paginação em resposta a ações diferentes, elas precisam herdar de uma loja base comum (ruim! Você está se trancando em um design específico ao usar herança) ou chamar uma função definida externamente de dentro do diretório 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, a paginação com Redux é natural graças à composição do redutor. São redutores até o fim, para que você possa escrever uma fábrica de redutores que gere redutores de paginação e depois usá-los em sua árvore de redutores . A chave para o fato de ser tão fácil é porque, 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 desfazer / refazer código sem usuário . Você pode imaginar conectar 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 - esse é o padrão pioneiro e descrito em detalhes na Elm Architecture, que foi influenciada pelo Flux.

Renderização do servidor

As pessoas estão processando bem no servidor com o Flux, mas, vendo que temos 20 bibliotecas do Flux tentando facilitar a renderização do servidor, talvez o Flux tenha algumas arestas no servidor. A verdade é que o Facebook não faz muita renderização de servidores, então eles não se preocuparam muito com isso e confiam no ecossistema para facilitar.

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 do Flux (assim como os novos Flux Utils ) agora sugerem o uso de classes em vez de singletons, para que você possa instanciar lojas por solicitação.

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

  • Se lojas são classes, como eu as crio e destruo com o despachante por solicitação? Quando registro lojas?
  • Como hidrato os dados das lojas e depois os reidrato no cliente? Preciso implementar métodos especiais para isso?

É certo que as estruturas do Flux (não o Flux de baunilha) têm soluções para esses problemas, mas eu as acho complicadas demais. Por exemplo, o Flummox pede para você implementar serialize()e deserialize()em suas lojas . Alt resolve isso melhor, fornecendo takeSnapshot()que serializa automaticamente seu estado em uma árvore JSON.

O Redux vai além: como existe apenas uma 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 loja e você pode ler o estado atual ou criar uma nova loja com um novo estado. Cada solicitação obtém uma instância de armazenamento separada. Leia mais sobre renderização de servidor com Redux.

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

Experiência do desenvolvedor

Na verdade, eu não pretendia que o Redux se tornasse uma biblioteca popular do Flux - escrevi enquanto trabalhava na minha palestra ReactEurope sobre recarregar as baterias com viagens no tempo . Eu tinha um objetivo principal: tornar possível alterar o código do redutor em tempo real ou até "mudar o passado", cruzando ações e ver o estado sendo recalculado.

Não vi uma única biblioteca do Flux 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 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 são emaranhados nos repositórios do 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 possui um ecossistema rico e de rápido crescimento . Isso ocorre porque ele fornece alguns pontos de extensão, como middleware . Ele foi projetado com casos de uso, como registro em log , suporte a promessas , observáveis , roteamento , verificações de desenvolvimento de imutabilidade , persistência etc., em mente. Nem todas serão úteis, mas é bom ter acesso a um conjunto de ferramentas que podem ser facilmente combinadas para trabalhar 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, recarregar a quente) sem introduzir o Dispatcher e o registro da loja.

Mantê-lo simples é importante, pois mantém você saudável enquanto implementa abstrações de nível superior.

Diferente da maioria das bibliotecas Flux, a superfície da API Redux é pequena. Se você remover os avisos, comentários e verificações de integridade do desenvolvedor, sã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 sobre as desvantagens de usar o Redux comparado ao Flux .

Dan Abramov
fonte
3
obrigado pela resposta ... sou novo em js .. na sua resposta você disse que o fluxo está usando o padrão de design singleton ... você pode me dizer em redux que tipo de padrão de design eles estão usando ... e no fluxo pode você me dizer onde eles estão usando o padrão Singleton ... você pode dar tanto um exemplo ... Eu entendi o que faz padrão de design a partir daqui Singleton
2
Comecei minha implementação Android / Java (Fluxxan) com base no Fluxxor (basicamente fluxo puro). Depois que vi o redux, fui vendido. Há algumas porções que mantive puramente fluentes, mas cara, sua lib é incrível!
Frostymarvelous 12/04
5
Você quer aprender Redux? apenas assistir a este vide: youtube.com/watch?v=ucd5x3Ka3gw
gsalgadotoledo
5
Escolhemos o redux por ser muito mais opinativo do que o fluxo. Estávamos constantemente brigando sobre como / para onde determinado código deveria ir etc. Redux removeu toda essa confusão para nós. Criamos aplicativos com redux para a Web e nativos para reagir e é incrível !!
SomethingOn
1
A linha github.com/reactjs/redux/blob/… foi a resposta para a pergunta que eu estava pesquisando por uma semana: como estruturar a loja e os redutores, para que várias instâncias do componente reutilizável usadas em diferentes contextos possam ser tratadas sem duplicar lógica. A resposta parece ser: use três níveis de armazenamento profundo: 1º nível: nome do componente ("paginação"), 2º nível: nome do contêiner ("stargazersByRepo"), 3 nível: a chave / ID exclusivo do contêiner ( ${login}/${name}) Muito obrigado!
Qbolec
101

No Quora, alguém diz :

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

Além disso, 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: Flux vs Redux

Mas se você ainda estiver interessado em saber mais, continue lendo.

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

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

Se você iniciar diretamente com o Redux, poderá acabar com um código com excesso de engenharia, um código mais difícil de manter e com ainda mais bugs e sem o Redux.

Dos documentos do Redux :

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

Gerenciar esse estado em constante mudança é difícil. Se um modelo pode atualizar outro modelo, uma exibição pode atualizar um modelo, que atualiza outro modelo, e isso, por sua vez, pode fazer com que outra exibiçã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 do seu estado. Quando um sistema é opaco e não determinístico, é difícil reproduzir bugs ou adicionar novos recursos.

Como se isso não bastasse, 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 no servidor, buscando dados antes de realizar transições de rota e assim por diante. Nos encontramos tentando gerenciar uma complexidade com a qual nunca tivemos que lidar antes, e inevitavelmente fazemos a pergunta: é hora de desistir? A resposta é não.

É difícil lidar com essa complexidade, pois estamos misturando dois conceitos muito difíceis de raciocinar pela mente humana: mutação e assincronicidade. Eu os chamo de Mentos e Coca-Cola. Ambos podem ser ótimos quando separados, mas juntos eles criam uma bagunça. Bibliotecas como React tentam resolver esse problema na camada de exibição removendo a assincronia e a manipulação direta do DOM. No entanto, o gerenciamento do estado dos seus dados fica a seu critério. É aqui que o Redux entra.

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

Também dos documentos do Redux :

Conceitos principais O
Redux em si é muito simples.

Imagine o estado do seu aplicativo ser descrito como um objeto simples. Por exemplo, o estado de um aplicativo de tarefas pode ser assim:

{
  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 ocorre para que diferentes partes do código não possam alterar o estado arbitrariamente, causando bugs difíceis de reproduzir.

Para alterar 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 descreve o que aconteceu. Aqui estão alguns exemplos de ações:

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

A imposição de que todas as alterações sejam descritas como uma ação nos permite entender claramente o que está acontecendo no aplicativo. Se algo mudou, sabemos por que mudou. Ações são como migalhas do que aconteceu. Finalmente, para unir estado e ações, escrevemos uma função chamada redutor. Novamente, nada de mágico nisso - é apenas uma função que toma estado e ação como argumentos e retorna o próximo estado do aplicativo. Seria difícil escrever essa 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 escrevemos outro redutor que gerencia o estado completo do nosso aplicativo chamando esses dois redutores pelas chaves de estado correspondentes:

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

Esta é basicamente toda a idéia do Redux. Observe que não usamos nenhuma API 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 é ​​apenas JavaScript, sem uso do Redux em si, suas APIs ou qualquer mágica.

Alireza
fonte
57

Você pode começar melhor lendo este post de Dan Abramov, onde ele discute várias implementações do Flux e suas vantagens e desvantagens no momento em que ele escrevia o redux: The Evolution of Flux Frameworks

Em segundo lugar, a página de motivações a que você vincula realmente não discute tanto as motivações do Redux quanto 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 possui vários repositórios que calculam as alterações de estado em resposta às interações da interface do usuário / API com os componentes e transmitem essas alterações como eventos nos quais os componentes podem se inscrever. No Redux, há apenas um armazenamento no qual cada componente assina. Na IMO, parece que o Redux simplifica e unifica ainda mais o fluxo de dados unificando (ou reduzindo, como Redux diria) o fluxo de dados de volta aos componentes - enquanto o Flux se concentra na unificação do outro lado do fluxo de dados - veja modelo.

Hal
fonte
27

Sou um dos primeiros a adotar e implementei um aplicativo de página única de tamanho médio usando a biblioteca do Facebook Flux.

Como estou um pouco atrasado para a conversa, apenas aponto que, apesar das minhas melhores esperanças, o Facebook parece considerar a implementação do Flux uma prova de conceito e nunca recebeu a atenção que merece.

Eu o encorajo a brincar com ele, pois expõe mais do trabalho interno da arquitetura Flux, que é bastante educacional, mas ao mesmo tempo não oferece muitos dos benefícios que bibliotecas como o Redux oferecem (que não são importante para projetos pequenos, mas se torna muito valioso para projetos maiores).

Decidimos que, seguindo em frente, mudaremos para o Redux e sugiro que você faça o mesmo;)

Guy Nesher
fonte
Desenvolvo o aplicativo Facebook Flux há seis meses. E ainda não tenho certeza se um tempo de migração vale os benefícios que o Redux oferece. Aprecio muito todos os seus comentários sobre os prós / contras do Redux over FB flux!
VB_
1
@VolodymyrBakhmatiuk para nós, trata-se principalmente de reduzir a quantidade de clichê que precisamos escrever + melhor tratamento de erros (o redux, por exemplo, gritará se você disparar uma ação que não foi definida em sua lista constante - o fluxo FB não e isso pode causar tudo tipos de problemas) Há alguns recursos mais avançados em fluxo, mas eu não usei-los ainda
Guy Nesher
1
@GuyNesher uma ação indefinida deve ser detectada no tempo de compilação, não no tempo de execução. O Flow (outra contribuição do Facebook) permite fazer isso.
Dominique PERETTI
@DominiquePERETTI - verdadeiro (também pode usar linting), mas isso não muda o fato de que não pegar o erro em tempo de execução é meio triste
Guy Nesher
Eu escrevi alguns ajudantes simples para lidar com o FBFlux, e na verdade parece ser menos elaborado e configurado para aplicativos do que todos os aplicativos Redux de exemplo que eu encontrei. Trabalhou em um aplicativo por mais de 9 meses entre dois desenvolvedores e nunca teve nenhum problema com a arquitetura.
rob2d
20

Aqui está a explicação simples do Redux sobre o Flux. O Redux não possui um despachante, ele depende de funções puras chamadas 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 o armazenamentoinsira a descrição da imagem aqui

Para mais informações: Flux vs Redux

Prathap Kudupu
fonte
Sobre várias lojas, agora é algo factível no Redux, no react-redux você pode adicionar uma chave para isolar lojas: redux.js.org/faq/storesetup exemplo de trabalho: github.com/Lemoncode/redux-multiple-stores
Braulio
6

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. O problema é que o Redux torna as coisas mais simples e limpas. Ele ensina algumas coisas sobre o Flux. Como por exemplo, o Flux é um exemplo perfeito de fluxo de dados unidirecional. Separação de preocupações 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.

Krasimir
fonte
5

De um novo adotante react / redux migrando do (alguns anos) do ExtJS em meados de 2018:

Depois de deslizar para trás na curva de aprendizado do redux, tive a mesma pergunta e pensei que o fluxo puro seria mais simples como o OP.

Logo vi os benefícios do redux sobre o fluxo, conforme observado nas respostas acima, e estava trabalhando no meu primeiro aplicativo.

Enquanto controlava a placa da caldeira novamente, experimentei algumas das outras bibliotecas de gerenciamento de estado, o melhor que encontrei foi revanche .

Foi muito mais intuitivo que o redux de baunilha, cortava 90% do padrão e cortava 75% do tempo que gastava em redux (algo que acho que uma biblioteca deveria estar fazendo), consegui alguns aplicativos corporativos indo imediatamente.

Também roda com as mesmas ferramentas de redux. Este é um bom artigo que cobre alguns dos benefícios.

Portanto, para qualquer pessoa que chegou a este post do SO pesquisando "redux mais simples", recomendo experimentá-lo como uma alternativa simples ao redux com todos os benefícios e 1/4 do clichê.

vanderwyst
fonte