React-Redux: Todos os estados dos componentes devem ser mantidos no Redux Store

89

Digamos que eu tenha um botão simples:

Quando clico no botão, o componente de cor muda entre vermelho e azul

Eu poderia alcançar esse resultado fazendo algo assim.

index.js

Button: onClick={()=>{dispatch(changeColor())}}
Color: this.props.color ? blue : red

container.js

connect(mapStateToProps)(indexPage)

action_creator.js

function changeColor(){
 return {type: 'CHANGE_COLOR'}
}

reducer.js

switch(){
case 'CHANGE_COLOR':
return {color: true}

mas isso é um monte de código para escrever algo que eu poderia ter alcançado em 5 segundos com jQuery, algumas classes e alguns css ...

Acho que o que realmente estou perguntando é: o que estou fazendo de errado aqui?

l2silver
fonte
6
react-redux não é vendido como algo mais curto que jquery. Definitivamente, é necessário algum código para colocá-lo em funcionamento.
zerkms de
1
Dê uma olhada aqui: github.com/rackt/redux/issues/1287 há muita discussão boa sobre o assunto.
m0meni de
1
obrigado @ AR7 isso é perfeito
12 de
1
@ l2silver sem problemas. Basicamente, a ideia é que se a cor desse componente não importa para ninguém, apenas mantenha esse estado interno ao próprio componente.
m0meni de
2
o problema mencionado pelo AR7 foi movido: github.com/reactjs/redux/issues/1287
ptim

Respostas:

154

Redux destina-se principalmente ao "estado do aplicativo". Ou seja, qualquer coisa relacionada à lógica do seu aplicativo. A visualização construída sobre ele é um reflexo desse estado, mas não precisa usar exclusivamente esse contêiner de estado para tudo o que faz.

Basta fazer estas perguntas: Esse estado é importante para o restante do aplicativo? As outras partes do aplicativo se comportarão de maneira diferente com base nesse estado? Em muitos casos menores, esse não será o caso. Faça um menu suspenso: O fato de estar aberto ou fechado provavelmente não afetará outras partes do aplicativo. Portanto, conectá-lo à sua loja provavelmente é um exagero. Certamente é uma opção válida, mas não lhe traz nenhum benefício. É melhor você usar this.statee encerrar o dia.

Em seu exemplo específico, a cor desse botão é alternada para fazer alguma diferença em outras partes do aplicativo? Se for algum tipo de botão liga / desliga global para a maior parte do seu aplicativo, ele definitivamente pertence à loja. Mas se você estiver apenas alternando a cor de um botão ao clicar no botão, poderá deixar o estado da cor definida localmente. A ação de clicar no botão pode ter outros efeitos que requerem um despacho de ação, mas isso é diferente da simples questão de qual cor deveria ser.

Em geral, tente manter o estado do seu aplicativo o menor possível. Você não tem que enfiar tudo lá. Faça-o quando for necessário ou faz muito sentido manter algo lá. Ou se torna sua vida mais fácil ao usar Dev Tools. Mas não sobrecarregue demais sua importância.

Tim Dorr
fonte
Ei, eu sei que nunca haverá uma resposta definitiva para esta pergunta, mas acho que sua lógica é muito correta aqui
12 de
3
Para ser honesto, eu realmente não entendo qual é o propósito de usar essa coisa de fluxo / redux. Qual era o problema com o modelo baseado em eventos?
Jayarjo
IMO, não é a resposta perfeita. Depende. Armazenar o estado da interface do usuário no estado de reação tornará o armazenamento redux limpo, mas acabará tornando o componente não funcional que é difícil de testar. Ao armazenar o estado da interface do usuário no estado de reação, haverá muitos esforços no desenvolvimento, porque temos que escrever redutores extras. No entanto, existem muitos pacotes que podem ajudá-lo a tornar seu estado da interface do usuário muito mais fácil de armazenar novamente , verifique redux.js.org/docs/faq/OrganizingState.html para obter mais detalhes.
Ron
19

Redux FAQ: Organizing State
esta parte do redux oficial doc respondeu bem a sua pergunta.

Usar o estado do componente local é bom . Como desenvolvedor, é sua função determinar quais tipos de estado constituem seu aplicativo e onde cada parte do estado deve residir. Encontre um equilíbrio que funcione para você e vá em frente.

Algumas regras básicas para determinar que tipo de dados devem ser colocados no Redux:

  • Outras partes do aplicativo se importam com esses dados?
  • Você precisa ser capaz de criar mais dados derivados com base nesses dados originais?
  • Os mesmos dados estão sendo usados ​​para conduzir vários componentes?
  • Existe valor para você em ser capaz de restaurar esse estado para um determinado momento (ou seja, depuração de viagem no tempo)?
  • Você deseja armazenar os dados em cache (ou seja, usar o que está no estado se já estiver lá, em vez de solicitá-lo novamente)?
chuck911
fonte
6

Com o propósito de destacar o ótimo link fornecido por @ AR7, e porque esse link mudou há um tempo:

Use React para o estado efêmero que não importa para o aplicativo globalmente e não sofre mutação de maneiras complexas. Por exemplo, uma alternância em algum elemento da IU, um estado de entrada de formulário. Use Redux para o estado que importa globalmente ou é alterado de maneiras complexas. Por exemplo, usuários em cache ou um rascunho de postagem.

Às vezes, você vai querer passar do estado Redux para o estado React (quando armazenar algo no Redux fica complicado) ou o contrário (quando mais componentes precisam ter acesso a algum estado que costumava ser local).

A regra prática é: faça o que for menos estranho.

Dan Abramov: https://github.com/reactjs/redux/issues/1287#issuecomment-175351978

ptim
fonte
-7

Sim, vale a pena se esforçar para armazenar todos os estados dos componentes no Redux . Se o fizer, você se beneficiará de muitos recursos do Redux, como depuração de viagem no tempo e relatórios de bugs reproduzíveis. Caso contrário, esses recursos podem ficar completamente inutilizáveis .

Sempre que você não armazena uma mudança de estado de componente no Redux, essa mudança é completamente perdida da pilha de mudanças Redux e a IU do seu aplicativo ficará fora de sincronia com a loja. Se isso não é importante para você, pergunte-se por que usar o Redux? Seu aplicativo será menos complexo sem ele!

Por motivos de desempenho, você pode querer recorrer a this.setState()qualquer coisa que despache muitas ações repetidamente. Por exemplo: armazenar o estado de um campo de entrada no Redux cada vez que o usuário digita uma chave pode resultar em desempenho ruim. Você pode resolver isso tratando-o como uma transação: assim que a ação do usuário for "confirmada", salve o estado final no Redux.

Sua postagem original menciona como o método Redux é "um inferno de muito código para escrever". Sim, mas você pode usar abstrações para padrões comuns, como o estado do componente local.

Kumar303
fonte
A depuração aprimorada é um objetivo útil e um bom recurso do redux, mas acho que a relação sinal / ruído também é importante. Pode-se registrar cada variável em uma base de código, mas isso acrescentaria muito código extra, tornando o código real mais difícil de ler e o registro seria difícil de pesquisar. Acho que o mesmo se aplica ao uso de redux. Ter todo o estado em redux pode melhorar a depuração, mas há um custo em código adicional e abstrações que podem tornar o código mais difícil de ler e até mesmo tornar algumas tarefas de depuração mais difíceis. (E quando as ferramentas redux dev travam, muitos dos ganhos de depuração são perdidos.)
JD Sandifer
1
Então por que usar Redux? Se você não colocar tudo no Redux, perderá todos os recursos, como devtools. Realmente é tudo ou nada. Se você usar setState () para um menu suspenso, como na primeira resposta deste post, não poderá usar devtools para depurar quaisquer problemas que seus usuários possam encontrar no menu suspenso. É pior quando você usa setState () para uma sobreposição porque não há como viajar no tempo antes e depois da exibição da sobreposição. Aplicar setState () aqui e ali é muito sujeito a erros porque o desenvolvedor tem que pensar constantemente no que pode falhar.
kumar303
Como uma resposta mais específica, registrar todas as variáveis ​​em uma base de código não é uma metáfora útil, pois a questão é se usar this.setState()ou dispatch(action...). Não é necessário usar em this.setState()todos os lugares, mas quando você precisa, minha sugestão é usar Redux em 99% dos casos, caindo this.setState()para 1% com base em questões de desempenho.
kumar303
Registrar todas as variáveis ​​me parece análogo a colocar tudo no Redux e igualmente desaconselhável como regra geral. Deixar algumas coisas de fora do Redux não nega os recursos de tudo que está no Redux, desde que o estado seja separado. Ou seja, ainda posso depurar minha lógica de chamada de API que é canalizada por meio do Redux, mesmo que o estado de uma caixa de seleção não seja. O OP tem um ponto - requer mais código em vários lugares para usar o Redux e talvez isso não se justifique no exemplo específico que eles listaram.
JD Sandifer
Você pode não conseguir depurar a lógica da API, na verdade. Esse é meu argumento. É realmente difícil prever os cenários em que você interromperá a viagem no tempo, então é melhor apenas colocar todos os estados (incluindo o estado da caixa de seleção) no Redux até que haja um problema de desempenho.
kumar303