Prefácio
Esta é a minha primeira postagem no Habré, então não julgue muito severamente (bem, ou julgue, mas de forma construtiva ).
Gostaria de observar que, nessa abordagem, a principal vantagem para mim é que delineamos e delegamos claramente a lógica de negócios por módulos. Um módulo é responsável por uma coisa e por algo muito específico. Ou seja, com essa abordagem, durante o processo de desenvolvimento, não há pensamento: "onde eu faria melhor (mais corretamente) fazer isso aqui?" Com essa abordagem, fica imediatamente claro onde exatamente a tarefa / problema deve ser resolvido.
Estrutura de arquivo
A estrutura do projeto + é padrão. Vou tentar dizer-lhe brevemente o que é usado a partir do que a própria montagem consiste

- Para preparar ações assíncronas, eu uso o middleware saga - uma coisa muito mais flexível e poderosa em relação ao middleware thunk
- Eu tenho componentes de estilo de módulos css. Na verdade, o conceito é o mesmo dos componentes estilizados, mas de alguma forma é mais conveniente para mim
- Uma camada intermediária entre contêineres e componentes que controla os adereços lançados da loja para o componente (filtragem, memoização e a capacidade de manipular convenientemente os nomes de campo de qualquer parte do estado do aplicativo) - selecionar novamente
Sagas redux
Documentação das sagas do Redux
A essência principal das sagas (e não apenas) é que separamos a lógica de negócios de trabalhar com solicitações por módulos. Cada saga é responsável por sua própria parte da API. Se eu precisasse obter dados do usuário e chamar uma ação após o recebimento bem-sucedido - faria isso em um módulo separado usersSagas.js
Os principais fatores (para mim) a favor das sagas são:
UPD (adicionou um ponto sobre o inferno da promessa)
- 1) O fato de que as ações, de forma amigável, devem ser apenas funções que dão um objeto. Se algumas das ações parecem diferentes (e é assim que acontece com o uso de thunk), gostaria de de alguma forma trazê-las para uma forma, porque de alguma forma isso não se encaixa em um único conceito. Eu gostaria de mover a lógica de solicitações e trabalhar com dados para solicitações em um módulo separado - é para isso que servem as sagas
- 2) Via de regra, se precisarmos fazer várias solicitações que usem dados de respostas a solicitações anteriores (queremos armazenar dados intermediários na loja, não é?), Redux-thunk nos convida a realizar uma nova ação na qual chamaremos outra solicitação de ação assíncrona, na qual mais 2 (por exemplo) as mesmas iterações são feitas. Parece um inferno promissor e geralmente parece confuso e, em princípio, inconveniente de usar (muitos aninhamentos), quanto a mim

módulos css / componentes estilizados
Costumo ver em projetos que as pessoas escrevem regras para componentes de estilo em alguns módulos css comuns.
Eu sou totalmente contra isso. O componente é um sistema isolado. Deve ser o mais reutilizável possível . Portanto, seria bom estilizá-lo separadamente.


Selecionar novamente
Os seletores têm vários objetivos:
- , . , , ( , ). , , . - getFilteredItems,
- ,
- . - . - . friends. , . , . , , friends contacts. reselect , , . — .
É por causa do último ponto que estou me afogando pelo fato de fazermos um reset a cada espirro. Selecione novamente - não apenas para memoização, mas também para um trabalho mais conveniente com o desenho da árvore de estado do aplicativo

Componentes e recipientes
Na abordagem clássica do React (sem usar bibliotecas para armazenar a loja como uma entidade separada), existem dois tipos de componentes - Componentes de apresentação e de contêiner. Normalmente (pelo que entendi), esta não é uma divisão de pasta estrita, mas sim uma divisão conceitual. Componentes de
apresentação são estúpidos. Eles são, na verdade, apenas o layout e a exibição de dados que foram inseridos neles como adereços. (um exemplo de tal componente pode ser encontrado acima em css-modules)
Container-Components - componentes que encapsulam a lógica de trabalhar com, por exemplo, o ciclo de vida de um componente. Eles são responsáveis por invocar uma ação responsável por solicitar dados, por exemplo. Eles retornam um mínimo de layout, porque o layout é isolado em componentes de apresentação.
Exemplo + -Container-Component:

Redux Containers são, na verdade, uma camada entre o lado redax e os componentes de reação. Neles, chamamos seletores e lançamos ações nos adereços de reação do componente.
SOU A FAVOR de ter seu próprio recipiente para cada espirro. Em primeiro lugar, dá a você mais controle sobre os adereços lançados no componente e, em segundo lugar, dá a você controle sobre o desempenho usando a seleção novamente.
Muitas vezes, precisamos reutilizar um componente, mas em diferentes partes da loja. Acontece que, para isso, precisamos apenas escrever outro contêiner e devolvê-lo quando necessário. Ou seja, a relação Muitos para um (muitos são contêineres, um é um componente. Para mim, é conveniente e conceitualmente)
Eu também gostaria de dar um exemplo mais frequente em favor da embalagem da maioria dos componentes.
Temos uma matriz de dados (uma matriz de usuários, por exemplo), que recebemos de alguma API. Também temos um pergaminho infinito, que o cliente não vai recusar. Rolamos para baixo por um longo tempo e carregamos cerca de 10k + de dados. E agora mudamos alguma propriedade de um usuário. Nosso aplicativo ficará muito lento porque:
- Anexamos o contêiner global a toda a página com a lista de usuários
- Ao alterar um campo de um elemento da matriz de usuários, uma NOVA matriz com novos elementos e índices retornados no redutor de usuários
- Todos os componentes colocados na árvore do componente UsersPage serão redesenhados. Incluindo cada componente do usuário (elemento da matriz)
Como evitar isso?
Fazemos contêineres em
- matriz com usuários
- elemento de matriz (um usuário)
Depois disso, no componente, que é empacotado em um contêiner de "matriz com usuários", retornamos o contêiner "elemento de matriz (um usuário)" com a chave (prop de reação necessária) lançada lá, índice
No contêiner "elemento de matriz (um usuário)" em mapStateToProps somos o segundo como argumento, tomamos os ownProps do componente que o contêiner retorna (entre eles o índice). Por índice, retiramos diretamente da loja apenas um elemento da matriz.
Além disso, será muito mais fácil otimizar o redesenho apenas do elemento alterado (toda a matriz é redesenhada, porque no redutor fizemos algum tipo de mapa que retorna uma NOVA matriz com novos índices para cada elemento) - aqui seremos ajudados por selecionar novamente a
matriz

do contêiner : o elemento do contêiner:

seletor de elemento:

Se houver alguma adição, vou lê-la com prazer nos comentários.