Redux: Série de screencasts Redux no Egghead

Criado em 24 nov. 2015  ·  69Comentários  ·  Fonte: reduxjs/redux

Se você está seguindo o repositório do Redux, mas ainda não mergulhou nele, ou está confuso sobre alguns de seus aspectos fundamentais, ficará feliz em saber que a Egghead acaba de publicar minha série Getting Started with Redux .

Ele cobre os mesmos tópicos que a parte “Basics” dos documentos, mas esperamos que se aprofunde um pouco mais e garanta que você _realmente_ entenda os fundamentos do Redux.

Pretendo criar mais conteúdo sobre Redux no Egghead – desta vez, apenas para assinantes. Ele apresentará tópicos mais avançados. Se você tiver sugestões específicas, por favor me avise neste tópico!

feedback wanted

Comentários muito úteis

@markerikson obrigado por me

Nota: Por conveniência, vou usar thunk para representar uma abordagem de middleware abreviada para assíncrona, seja realmente redux-thunk ou redux-promise, ou qualquer outra coisa.

Sua camada de interface do usuário apenas conecta as interações do usuário aos manipuladores. Quando alguém clica em um botão, sua interface do usuário é manipulada para chamar _some_ handler. Frequentemente, o componente recebe esses manipuladores como props --- talvez um criador de ação vinculado, por exemplo. A interface do usuário não sabe o que acontece quando chama um manipulador --- apenas o chama.

Não faz diferença para a camada de interface do usuário se o "manipulador" despacha uma função (para ser tratada pelo middleware) ou se executa uma chamada assíncrona e _então_ despacha uma ação simples --- a interface do usuário é completamente agnóstica (ou pelo menos, _pode_ ser agnóstico)

Uma grande parte do seu "aplicativo" está nesses "manipuladores", independentemente de você estar usando thunks ou não. Em um aplicativo típico de react/redux, esses "manipuladores" geralmente são criadores de ação de algum tipo. Você pode escrever todas as suas coisas assíncronas como thunks e despachá-las. Ou você pode escrever todas as suas coisas assíncronas como funções que aceitam dispatch como argumento. Da perspectiva do componente, é someHandler(dispatch) OU dispatch(someHandler()) , ou no caso de criadores de ações vinculadas transmitidos de cima para baixo, é apenas someHandler() em ambos os casos. Você poderia construir uma versão de bindActionCreators que mascararia completamente essa diferença da camada de interface do usuário.

Se você me der um aplicativo react/redux escrito com criadores de ação usando redux-thunk, eu poderia trocar completamente o redux-thunk e usar uma abordagem não-middleware sem _fundamentalmente_ alterar qualquer camada da interface do usuário. (nota: estou ignorando onde/como você injeta getState , mas _acredito_ que é um detalhe menor aqui).

Portanto, estou tendo problemas para aceitar que a distinção entre "dentro" e "fora" é "nível do aplicativo" ou "nível da interface do usuário".

Eu aprecio a discussão, e espero não estar sendo negativo.

Todos 69 comentários

:+1:

  1. Estado do componente local vs. estado global
  2. Ação tratada por vários redutores vs. relação ação-redutor de 1 para 1
  3. Manipulação de cadeias de ação (especialmente assíncronas), quando a segunda ação deve ser acionada logo após a conclusão da primeira.
  4. Técnicas de otimização para evitar novas rerenizações desnecessárias (ações em lote, reseleção etc.).

:+1:

Acabei de assistir os primeiros 16 episódios da série e acho que eles são um excelente recurso que provavelmente usaremos para treinamento interno na empresa em que trabalho. No entanto, o fato de você usar apenas objetos simples e deep-freeze para sua árvore de estados e nunca usar ou se referir a bibliotecas imutáveis como

Seria ótimo saber sua opinião sobre isso.

Colocar Immutable na mistura confundiria os iniciantes que precisariam aprender a diferenciar entre Redux e API Immutable, podem assumir que Immutable é necessário, etc. É uma boa ideia para algumas lições avançadas!

Colocar Immutable na mistura confundiria os iniciantes que precisariam aprender a diferenciar entre Redux e API Immutable, podem assumir que Immutable é necessário, etc. É uma boa ideia para algumas lições avançadas!

Ok, faz sentido. É bom saber o que você pensa por trás dessa decisão :-).

O que @smashercosmo disse :+1:

Testes unitários. TDD.

O que @cateland disse :+1:

Devo dizer que estou muito impressionado com seu conjunto de habilidades, sendo capaz de criar excelentes bibliotecas js com extensa documentação e tutoriais concisos dessa maneira.

Depois de ver todos os vídeos, tenho vários comentários sobre os vídeos específicos que enviarei pelo correio. A conclusão, porém, é que isso é muito mais do que uma introdução ao Redux. Você cobre práticas de código e arquitetura de componentes e muito mais. É realmente incrível e muito pedagógico. Eu acho que os vídeos podem ser divididos em três grupos. Redux básico, redux nos bastidores e redux com react.

Para os próximos vídeos, gostaria de ver menos conceitos específicos de reação e mais ações e testes assíncronos.

Muito bem feito, continue assim! :)

No vídeo 21 você nota que o componente TodoApp não precisa mais ser uma classe, pode ser uma função. Seria ótimo se você pudesse explicar como chegou a essa conclusão - por que esse é um candidato adequado para ser um componente funcional e que benefício isso traz?

Isso é tão bom.

O item 3 da lista do @smashercosmo é algo que eu gostaria de saber também.

o que @wpannell disse! Teste de unidade/TDD!

Também adoraria ver vídeos sobre os tópicos abordados nos documentos avançados.

Em que especificamente você está interessado em relação aos testes de unidade?
As lições 5, 11, 12 dão uma ideia de como testar a unidade dos redutores.

...Esta é uma boa pergunta. O processo mudaria muito quando fossem testes de mocha?

Na verdade, não. Mas acho que esse é um bom tópico para uma série de lições avançadas. Redutores de teste de unidade, criadores de ação, componentes etc.

Primeiramente, ótimos vídeos. Já entendi o redux mas foi refrescante.
Se você estiver criando vídeos mais avançados, posso sugerir ações assíncronas / middleware.
Não pense que o teste de unidade realmente precisa de qualquer cobertura. Você pode simplesmente chamar suas funções redutoras e afirmar sobre elas?

Sim, acho que não é muito mais do que envolver os expect s em testes de mocha. :afirmativo:

Felizmente tudo é tão simples!

Imutabilidade com hashes de ID de objeto (por exemplo, [post._id]: {...post} ).

Eu me vejo confiando demais em uma função reduce para pegar uma matriz de entidades de API e produzir um hash de ID com ela. Eu sei que o normalizr vai lidar com isso, mas eu gostaria de vídeos semelhantes aos vídeos do EggheadIO, onde você nos leva do ponto A ao B. Não é apenas uma coisa baseada em Redux, mas está fortemente entrelaçada.

@raquelxmoss

No vídeo 21 você nota que o componente TodoApp não precisa mais ser uma classe, pode ser uma função. Seria ótimo se você pudesse explicar como chegou a essa conclusão - por que esse é um candidato adequado para ser um componente funcional e que benefício isso traz?

Isso foi realmente algum planejamento de aula desleixado da minha parte. Eu não percebi até muito tarde que eu poderia torná-lo um componente funcional desde o início. O benefício de usar funções sobre classes é a simplicidade, então faça isso sempre que puder. Basicamente, se você não precisa de ganchos de ciclo de vida como componentDidMount ou estado, use componentes funcionais.

Eu acharia útil uma lição sobre como podemos dividir esses pedaços de código em uma estrutura de diretório real. Eu sei que, desde que tudo esteja lá, provavelmente funcionará, mas talvez as convenções recomendadas de nomenclatura de pastas (componente / contêiner / armazenamento / redutor etc.), que tipos de arquivos vão para qual pasta e assim por diante seria bom.

Eu também gostaria de composição redutora avançada.

Reutilizando componentes complexos (que são compostos por um redutor ou vários redutores, um conjunto de ações, criadores de ações, talvez acessando alguma API do lado do servidor, vários componentes React - como redux-form, mas mais específicos do aplicativo real). Isso também inclui organizar a estrutura de diretório modular.

Assisti tudo, muito bom! Apreciei o uso da sintaxe ES6/7 ( Object.assign -like), componentes de função React 0.14 e evitando coisas imutáveis.

Talvez um vídeo explicando a arquitetura de código recomendada.

E atualizando o documento para usar sintaxes ES6/7? (as relações públicas são bem-vindas nessa direção?)

Testes unitários, criando API Middleware, fazendo OAuth/algum tipo de autenticação de usuário com Redux, usando Immutable com redux (como configurar, melhores práticas etc.)

Esta série serve como uma ótima introdução ao Redux, o estado de átomo único e filosofias relacionadas. Achei que você fez um bom trabalho ao se concentrar nos princípios fundamentais, evitando induzir a sobrecarga cognitiva. O ambiente em que você trabalhou também é facilmente replicável, o que torna a parte prática ainda mais acessível.

@gaearon O que você acha de estruturar ações nos vídeos de exemplo como um { type: string, payload: Object } padrão desde o início? Estou falando do exemplo da lista de contador, onde a carga útil é colocada no próprio objeto de ação; { type: string, index: number } . Isso me parece um anti-padrão.

O que você acha de estruturar ações nos vídeos de exemplo como um padrão { type: string, payload: Object } desde o início? Estou falando do exemplo da lista de contador, onde a carga útil é colocada no próprio objeto de ação; { tipo: string, índice: número }. Isso me parece um anti-padrão.

Não é um anti-padrão de forma alguma. É um objeto de ação normal. FSA é bom, mas é uma _convenção_. Nada no Redux em si depende ou se beneficia dessa convenção, então não queremos forçá-la.

As pessoas costumavam pensar em todos os tipos de coisas mágicas sobre payload , source na documentação original do Flux. Eles copiaram cegamente essas coisas sem entender por que elas existem e avaliar cuidadosamente se precisam delas. Mais tarde, eles reclamaram que o Flux era complexo e detalhado, quando, na verdade, em muitos casos, eles mesmos copiavam as partes detalhadas (mas não essenciais).

Nestas aulas eu ensino apenas as partes essenciais do Redux. Observe como não introduzo constantes — porque as pessoas se concentram demais nelas e não percebem que elas realmente não importam. É mais provável que você entenda os benefícios das constantes depois de cometer alguns erros de digitação em strings, em vez de colocá-los nos vídeos tutoriais desde o início. Acho que o mesmo vale para outras convenções como a FSA – de qualquer forma, use-a se achar conveniente, mas não vou pregá-la se as lições não exigirem.

@gaearon OK, estou com você então, na esperança de que aqueles que se acostumaram com a abordagem simples e não estruturada não tornem aplicativos maiores incontroláveis ​​por não aplicar nenhuma convenção.

@sompylasar

Acho que exemplos exibem convenções melhor do que tutoriais em vídeo. Exemplos são a terra opinativa de “aqui está como vou estruturar algum código em torno desses princípios”, e os vídeos são sobre esses próprios princípios. É por isso que você verá convenções diferentes em exemplos diferentes e, antes de iniciar um projeto, a maioria das pessoas analisa diferentes exemplos para experimentar diferentes maneiras de fazer isso.

Além disso, não há absolutamente nada desestruturado em não seguir a FSA. { type: 'STUFF', id: 1 } não é inerentemente pior que { type: 'STUFF', payload: { id: 1 } } . É apenas uma questão de gosto e (às vezes) convenção de ferramentas. Manter objetos de ação payload menores não está tornando-os mais difíceis de trabalhar.

Temos um punhado de lições de teste de unidade redux saindo em breve no egghead 😄

Nós adiamos QUAISQUER aulas de Redux por algum tempo para que Dan tivesse a primeira chance. Totalmente vale a pena esperar, e então alguns.

"Construir um Aplicativo com Redux Idiomático" seria um curso avançado maravilhoso 👍

@joelooks os dois soam incríveis!

Eu gostaria de ver você configurar um projeto usando webpack e hot reloading em vez de usar jsbin. Leve isso para o mundo real. Eu sei que não é específico para redux, mas acho que se encaixaria bem e você é o homem certo para ensinar isso :)

@kevinrenskers não é uma série de vídeos, mas se você se sentir como dissecar algo, são algumas realmente grande exemplo boilerplates você pode referência!

Aqueles que pediram uma estrutura de projeto para o exemplo de Dan e configuração do Webpack.

Por favor, verifique isso https://github.com/urbanvikingr/todo.

Eu me comprometi a atualizar o Redux com React doc para ficar alinhado com o código de Dan dos vídeos. Será feito nas próximas duas semanas - meu projeto de férias :) - fique atento.

Minha lista de desejos para vídeos do Egghead.io:
teste de ação/redutor com Jasmine
mergulho profundo no middleware (thunk / promessas)

Os screencasts são uma introdução muito útil ao Redux. O que eu gostaria de ouvir é a maneira Redux de fazer roteamento e renderização do lado do servidor

@grigio Você pode estar interessado nesta discussão https://github.com/rackt/redux/issues/1145 sobre roteamento

@urbanvikingr obrigado, inscrito. A enquete parece encerrada, mas eu teria votado #1168

As lições são realmente muito boas, mas é uma distração que quando você diz "loja", soa como "tarefa".

Todo mundo aqui notou e se distraiu com isso. Eles são politicamente corretos demais para trazer isso à tona. Então, sim, eu decidi ser _esse_ cara, caso ninguém mais fosse :)

Eu vou ficar melhor em falar inglês eventualmente. Por enquanto isso é o melhor que posso fazer ;-)

@gaearon Você fez um ótimo trabalho explicando o Redux. Parabéns a você e suas conquistas de código aberto.

Conjunto incrível de lições. Gostei especialmente de como você reimplementou cada uma das funções principais do Redux do zero de uma maneira "ler a fonte". Apoiando alguém que ficou impressionado com a clareza dos tutoriais e toda a documentação para o Redux. Até agora, como alguém que está se atualizando em dois anos de avanços no frontend, os conceitos têm sido difíceis de entender, mas os documentos têm sido incrivelmente úteis para isso. Continue assim, e obrigado!

(Também não escute @jugimaster , nem todo mundo se distraiu com seu sotaque e foi "politicamente correto demais para falar sobre isso", ou mesmo se importava que você tivesse um sotaque.)

@ianstormtaylor
Aliás, não é sotaque :)

Eu também não "me importei", mas com certeza estava distraído!

Mas por outro lado, como alguém que estudou seis línguas estrangeiras, eu sempre me preocupei em falar um idioma corretamente e, para isso, eu pessoalmente aprecio alguém apontando meus erros.

Oi @gaearon ,

Amei seu curso com certeza. Bom trabalho! Foi muito útil.

Adicionei três videoaulas de teste do Redux ao meu curso recente do Egghead:
https://egghead.io/series/react-testing-cookbook

Minha esperança é que eles sejam complementares a todo o trabalho incrível que você fez!

Curso sólido!

Melhora não apenas o conhecimento do Redux, mas também o conhecimento das práticas modernas em geral! Continue fazendo coisas tão boas :+1: :tada:

ei, acabei de perceber que não há um link/referência para o código nos vídeos. Talvez usuários óbvios, e talvez simples o suficiente, pudessem simplesmente copiar os vídeos; mas acho que muitas pessoas poderiam se beneficiar de um repositório com o código exato nos vídeos - por que não?

Trechos de código para cada lição estão disponíveis para assinantes do Egghead. :-)
Os vídeos são gratuitos, mas a plataforma precisa ganhar dinheiro para poder investir em mais cursos, enviar equipamentos para os instrutores, hospedar os vídeos, melhorar o site e assim por diante.

Dito isso, temos uma pasta examples/todos que corresponde muito bem ao curso.

... legal, estou sentindo falta então? Procurando links...

@gaearon pede desculpas, apenas revisitou os vídeos. o código está logo ali :)... assisti os vídeos, comprei assinatura, assisti outros... apenas voltei para os vídeos redux realmente logados. aplausos.

A propósito, algumas pessoas reclamaram que as transcrições são imprecisas.
Por favor, envie PRs para corrigi-los: https://github.com/eggheadio/egghead-redux-transcripts

@gaearon , decidi usar redux e encontrei os vídeos redux no egghead. Os vídeos realmente me ajudaram a começar a aprender redux. No futuro, seria ótimo ver mais exemplos do mundo real.

Portanto, minha sugestão para o treinamento de vídeo redux daqui para frente seria composição avançada, um mergulho mais profundo na refatoração e definitivamente como usar a reseleção. Você parece ter uma intuição sobre quando refatorar. Portanto, como a programação funcional está intimamente ligada ao redux, obter algumas dicas de você sobre quando refatorar e como identificar uma função que faz uma coisa bem seria muito útil.

No aplicativo que estou construindo, tenho várias coleções de dados grandes e preciso colocá-las em tabelas e fazer coisas como classificar e paginar os dados. Estou tendo dificuldade em decidir quando usar seletores e quando usar ações de criação. Atualmente tenho a ação USERS_SORT_TABLE e a ação SORT_TABLE porque tenho os usuários armazenando "herdando" algum estado da tabela. Fiz isso porque não queria que uma ação SORT_TABLE em um repositório de tarefas fosse classificada pelo repositório do usuário.

Eu sei que minha solução não está DRY, mas não tenho certeza de como fazê-lo corretamente. Do jeito que está, vou ter que criar uma ação "SOMETHING"_SORT_TABLE para cada loja que quero preencher uma tabela, o que sei que está errado, mas não sei o caminho certo. Outro efeito colateral é que o nome da minha ação está ficando enorme porque tenho que separar diferentes lojas prefixando seu nome na ação. Isso não pode estar certo.

Aqui está algum código de exemplo:

/* actions.js */
// ...
export const USER_MOVE_COLUMN = 'USER_MOVE_COLUMN'

export function userMoveColumn (columnIndex, moveToIndex) {
  return {
    type: USER_MOVE_COLUMN,
    columnIndex,
    moveToIndex
  }
}

export const DATA_TABLE_MOVE_COLUMN = 'DATA_TABLE_MOVE_COLUMN'
// ...

/* reducers.js */
// ...
export default function user (state=userInitialState, action) {
  switch (action.type) {
    // ...
    case USER_MOVE_COLUMN:
      return dataTable(state, assign(
        action,
        {type: DATA_TABLE_MOVE_COLUMN}
      ))
    // ...
    default:
      return state
  }
}
// ...
export default function dataTable (
  state=dataTableInitialState,
  action,
  key='dataTable')
{
  switch (action.type) {
    // ...
    case DATA_TABLE_MOVE_COLUMN:
      return {
        ...state,
        [key]: {
          ...state[key],
          columns: move(
            state[key].columns, action.columnIndex, action.moveToIndex
          )
        }
      }
    // ...
    default:
      return state
  }
}

Então você pode ver que eu criei uma dependência entre a tabela e o armazenamento "modelo" que eu não deveria ter (o armazenamento do modelo deve usar a chave de coleção para sua matriz de objetos). E o dataTable manipula o estado do redutor "pai", o que não deveria. Ocorreu-me que preciso usar um seletor lá, mas no momento em que escrevi isso, estava tentando evitar a duplicação de uma loja grande apenas para alterar o que estava visível na interface do usuário.

Então, atualmente estou lutando para aprender a reselecionar para resolver alguns desses problemas e técnicas de refatoração para resolver alguns dos outros. O primeiro curso Redux foi o suficiente para me tornar perigoso. Agora eu gostaria de aprender como fazer isso direito. :)

Espero que tenha sido útil e não muito detalhado. Tentando dar um feedback claro e honesto.

Para qualquer alma bondosa que possa me ajudar, já encontrei /examples/real-world/reducers de outro comentário de Dan e atualmente estou reformulando alguns dos problemas que descrevi acima. Não queria que você perdesse tempo tentando ajudar se eu encontrasse uma solução.

Obrigado pelo aviso :)

integrar o redux-devtools dentro do meu projeto foi uma grande dor para mim .. eu teria (e ainda vou) apreciar uma série egghead que descreve o que está lá fora e como / quando usá-lo. Eu li o PR onde você descreve quando usar o que .. mas fiquei tão confuso há tantas coisas por aí hmr, transform 3, redux hot reloader é diferente de react hot reloader e assim por diante ..

Para qualquer um que esteja lutando com alguns dos problemas que descrevi acima, criei um projeto que permite remover a maioria, se não todo o clichê no Redux, bem como as ações de namespace. Veja isso aqui

@granteagon Esse casal não faz redutores para criadores de ação? Um dos princípios básicos de design no Redux é que _redutores devem ser desacoplados de ações_. Qualquer redutor pode ouvir qualquer ação. Não há mapeamento 1:1 entre eles. Caso contrário, é difícil para diferentes partes da árvore de estado alterar seu estado independentemente em resposta às mesmas ações.

Observei que a maioria das pessoas que cria wrappers ou abstrações em cima da criação de ação/redutor tende a supor que elas sempre serão diretamente acopladas. É certo que, no meu aplicativo, até agora _a maioria_ das minhas ações têm exatamente um bloco correspondente de lógica de manipulação, mas definitivamente houve vários em que várias partes da árvore precisam ser atualizadas.

@gaearon @markerikson Faz par de redutores para criadores de ação. No entanto, 90% do tempo, tudo bem ou até mesmo desejado. Nos outros 10% do tempo, você ainda pode usar uma abordagem codificada à mão. Vou pensar sobre o que você disse e considerá-lo para o desenvolvimento futuro.

@granteagon @gaearon

Tendo usado uma abstração local semelhante ao reduxr, eu diria que não há nenhum acoplamento adicional aqui. Nada está forçando o mapeamento 1:1 entre ações e redutores. Você ainda pode ter dois redutores em duas fatias diferentes ouvindo a mesma ação:

const counterReducersA = {
  // this counter increments by 1 each time
  increment: (state, action) => state + 1
}

const counterReducersB = {
  // this counter increments by 2 each time
  increment: (state, action) => state + 2
}

const counterA = reduxr(counterReducersA, 0);
const counterB = reduxr(counterReducersB, 0);

const rootReducer = combineReducers({
  counterA: counterA.reducer,
  counterB: counterB.reducer
});

store.dispatch(counterA.action.increment());  // increments both counters

Claro, se você tiver mais de uma função "redutor" com o mesmo nome (ou seja, respondendo à mesma ação), implicitamente ambos precisam "esperar" que a carga útil da ação esteja em uma determinada forma --- o que é completamente análogo ter dois redutores no vanilla redux, ambos manipulando a mesma constante type --- ambos devem esperar a mesma forma de ação.

Talvez eu tenha entendido mal o que você quer dizer com acoplamento, @gaearon ?

Acho que mostrar um fluxo assíncrono sem middleware antes de mostrar a implementação de conversão pode ser útil.

Um pouco relacionado, mas embora a documentação tenha sido incrivelmente útil, esta declaração na página de fluxos assíncronos realmente me tirou do caminho em retrospectiva: "Sem middleware, a loja Redux suporta apenas fluxo de dados síncrono".

@battaile : isso é porque é verdade :) Sem middleware, qualquer assincronia tem que acontecer completamente fora do Redux (portanto, provavelmente na sua camada de interface do usuário, como componentes React). Toda vez que você chamar store.dispatch , a ação irá direto para a função redutora, não passe Go, não colete $200, não faça nenhuma parada ao longo do caminho para chamadas AJAX.

Os aprimoradores de loja permitem que você embrulhe funções como dispatch com sua própria versão e, portanto, applyMiddleware fornece a abstração de um "pipeline de middleware" antes que algo atinja a função dispatch da loja real . Isso basicamente fornece uma brecha onde você pode pular e fazer qualquer coisa assíncrona que quiser, _dentro_ do fluxo Redux padrão.

Então, sem middleware, você ainda poderia fazer coisas totalmente assíncronas... tudo teria que acontecer totalmente separado de qualquer coisa realmente relacionada ao Redux.

é porque é verdade :)

Eu não disse que era falso, eu disse que me tirou da pista :)

Eu só queria fazer algo como o seguinte, o que parecia implicar que eu não poderia:

const mapDispatchToProps = (dispatch) => ({
  onclick(searchTerm) {
    dispatch(actions.requestOrders(searchTerm));

    return fetch('http://localhost:49984/Order/Search?search=' + searchTerm)
      .then(response => response.json()).then(response => {
        dispatch(actions.receiveOrders(searchTerm, response));
      })
      .catch((err) => {
        dispatch(actions.receiveOrdersError('An error occurred during search: ' + err.message));
      });
  },
});

Eu percebo que isso pode facilmente ficar feio, mas conceitualmente acho que é útil ver. Ou pelo menos foi no meu caso.

Concordo que "Sem middleware, a loja Redux suporta apenas fluxo de dados síncrono". é enganoso.

Tecnicamente, se você quiser fazer uma distinção entre "dentro" e "fora", a afirmação pode ser verdadeira, mas se levar as pessoas a acreditar que a única maneira de fazer assíncrona é adicionando middleware, talvez possamos reformulá-la ou elaborar isto.

Sim, a diferença é que o comportamento assíncrono está tecnicamente acontecendo mais no nível do componente, em vez de "dentro" de dispatch . Uma distinção menor, mas válida.

Eu não acho que alguém está realmente argumentando que a afirmação não é tecnicamente correta.

@markerikson Apenas curioso se você tem algum exemplo concreto onde a distinção entre dentro e fora importa?

Um exemplo pode ser se você deseja que o middleware na cadeia _antes_ de seu middleware assíncrono possa ver sua conversão despachada (ou promessa, etc). Não tenho certeza do que esse middleware faria, mas suponho que seja viável querer uma coisa dessas.

Mmm... não tenho certeza sobre exemplos "concretos" especificamente. No geral, a distinção entre "fora" e "insie" é uma questão de saber se isso acontece _antes_ de você chamar dispatch na primeira vez ou _depois_. Se está "fora" e "antes", então toda a sua assincronia e lógica estão mais ligadas à camada de visualização, seja React, Angular ou qualquer outra coisa. Se for "dentro" e "depois", sua assincronicidade e lógica estão no nível da loja e _não_ vinculadas à camada de visualização.

Este é realmente o ponto que eu estava tentando fazer em uma discussão do Reddit hoje cedo: https://www.reddit.com/r/reactjs/comments/4spbip/has_anyone_inserted_a_controllerpresenter_layer/ .

A questão de "que ações eu despacho e quando eu as despacho?" é uma parte central da sua lógica de negócios, com a outra metade sendo "como atualizo meu estado em resposta a essas ações?". Se o gerenciamento de ação está em thunks e sagas e tal, então realmente não importa se esse código foi iniciado por um React Component, um Angular Controller, um manipulador de cliques jQuery, uma instância de componente Vue ou qualquer outra coisa. Sua lógica principal está fora da camada de interface do usuário, e a camada de interface do usuário é realmente apenas responsável por extrair os dados necessários da loja, exibi-los e transformar as entradas do usuário em uma chamada de função lógica do aplicativo.

Então, nesse sentido, eu diria que a questão de "dentro" versus "fora" importa, porque é uma distinção conceitual entre se sua lógica está no nível do aplicativo ou no nível da interface do usuário.

@markerikson obrigado por me

Nota: Por conveniência, vou usar thunk para representar uma abordagem de middleware abreviada para assíncrona, seja realmente redux-thunk ou redux-promise, ou qualquer outra coisa.

Sua camada de interface do usuário apenas conecta as interações do usuário aos manipuladores. Quando alguém clica em um botão, sua interface do usuário é manipulada para chamar _some_ handler. Frequentemente, o componente recebe esses manipuladores como props --- talvez um criador de ação vinculado, por exemplo. A interface do usuário não sabe o que acontece quando chama um manipulador --- apenas o chama.

Não faz diferença para a camada de interface do usuário se o "manipulador" despacha uma função (para ser tratada pelo middleware) ou se executa uma chamada assíncrona e _então_ despacha uma ação simples --- a interface do usuário é completamente agnóstica (ou pelo menos, _pode_ ser agnóstico)

Uma grande parte do seu "aplicativo" está nesses "manipuladores", independentemente de você estar usando thunks ou não. Em um aplicativo típico de react/redux, esses "manipuladores" geralmente são criadores de ação de algum tipo. Você pode escrever todas as suas coisas assíncronas como thunks e despachá-las. Ou você pode escrever todas as suas coisas assíncronas como funções que aceitam dispatch como argumento. Da perspectiva do componente, é someHandler(dispatch) OU dispatch(someHandler()) , ou no caso de criadores de ações vinculadas transmitidos de cima para baixo, é apenas someHandler() em ambos os casos. Você poderia construir uma versão de bindActionCreators que mascararia completamente essa diferença da camada de interface do usuário.

Se você me der um aplicativo react/redux escrito com criadores de ação usando redux-thunk, eu poderia trocar completamente o redux-thunk e usar uma abordagem não-middleware sem _fundamentalmente_ alterar qualquer camada da interface do usuário. (nota: estou ignorando onde/como você injeta getState , mas _acredito_ que é um detalhe menor aqui).

Portanto, estou tendo problemas para aceitar que a distinção entre "dentro" e "fora" é "nível do aplicativo" ou "nível da interface do usuário".

Eu aprecio a discussão, e espero não estar sendo negativo.

Esse curso é ótimo. Fechando isso para que as pessoas possam direcionar seus comentários para o repositório de notas da comunidade para o curso: https://github.com/tayiorbeii/egghead.io_redux_course_notes

Além disso, não deixe de conferir a próxima série que Dan montou! https://egghead.io/courses/building-react-applications-with-idiomatic-redux

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

captbaritone picture captbaritone  ·  3Comentários

parallelthought picture parallelthought  ·  3Comentários

cloudfroster picture cloudfroster  ·  3Comentários

caojinli picture caojinli  ·  3Comentários

timdorr picture timdorr  ·  3Comentários