da2k / curso-reactjs-ninja

915 stars 322 forks source link

M3#A14 #463

Closed ghost closed 4 years ago

ghost commented 4 years ago

Não ficou muito claro como o CounterContainer é renderizado, pois não encontrei um import dele em nenhum outro componente. Reconheço que a dúvida possa ser pelo pouco conhecimento que tenho de Webpack + Node.js.

O App é exportado assim, com o Counter sem nenhum prop:

import React from 'react'
import Counter from 'components/counter'

const App = () => (
  <Counter />
)

export default App

O App é passado para o AppContainer como NextApp:

const renderApp = (NextApp) => {
  render(
    <AppContainer>
      <Provider store={store}>
        <NextApp />
      </Provider>
    </AppContainer>,
    document.querySelector('[data-js="app"]')
  )
}

renderApp(App)

if (module.hot) {
  module.hot.accept('./app', () => {
    const NextApp = require('./app').default
    renderApp(NextApp)
  })
}

O CounterContainer retorna o Counter com os props do Provider, porém ele não parece ser importado em nenhum lugar:

render () {
    return (
      <Counter
        counter={this.props.counter}
        increment={this.increment}
        decrement={this.decrement}
      />
    )
  }

Como, então, temos o CounterContainer na renderização?

image

Tem algo a ver a operacionalidade do módulo react-hot-loader? Ou é algo que o connect está fazendo? Eu não considerei essa segunda possibilidade, porque na aula anterior não havia ainda instalação do react-redux e o CounterContainer também era renderizado.

Tem a ver com essa pergunta no StackOverflow? Porque eu vi que tem dois index.js, src/index.js e components/index.js.

@fdaciuk

fdaciuk commented 4 years ago

Oi @mjfneto! Consegue subir seu código aqui no GitHub? Fica mais fácil ver o código todo pra entender o que está acontecendo, e facilita também para apontar onde estão as coisas :)

ghost commented 4 years ago

Oi @fdaciuk. É o código da aula (07-react-counter) mesmo.

fdaciuk commented 4 years ago

Legal @mjfneto, já vi aqui :)

Só antes de partirmos para a dúvida, eu escrevi um artigo sobre ES Modules, cobrindo tudo o que você precisa saber sobre eles. Acredito que essa leitura vai tirar várias dúvidas sobre como funciona o novo sistema de módulos do JS,e vai deixar mais clara a ideia do que aconteceu nessa aula :)

Sobre a sua dúvida: sim, tem a ver com o arquivo src/components/counter/index.js.

Quando nós fizemos o import do componente Counter no arquivo app.js, se você perceber, o caminho passado foi 'components/counter', certo?

A pergunta é: para qual arquivo esse caminho está apontando?

Se olharmos a configuração do nosso webpack, nessa linha nós temos um alias que diz que, sempre que fizermos um import iniciado com components, o que nós queremos é usar o diretório ./src/components. Tudo bem até aqui?

Mas o nosso import é components/counter. O counter, nesse caso, é um diretório, e dentro desse diretório temos dois arquivos index.js e counter.js. Qual desses arquivos será usado ao fazer esse import?

Quando você passa no import apenas um diretório, e não o nome de um arquivo, o webpack vai sempre verificar se existe nesse diretório um arquivo chamado index.js. Se esse arquivo existir, é esse arquivo que será importado :)

Esse nome index é um padrão que veio do HTML, onde esse seria sempre o primeiro arquivo a ser carregado em um diretório (index.html), se nenhum outro nome de arquivo fosse passado.

O mesmo foi também padronizado no Node.js: sempre que você fizer um import no Node.js (com require) e não passar o nome do arquivo, somente um diretório, o Node vai tentar buscar por um arquivo index.js antes de dizer que o caminho não existe, se esse arquivo não existir.

E como o webpack foi escrito usando JavaScript (Node.js, no caso), ele usa o mesmo padrão.

Então, quando nós usamos o caminho components/counter, na verdade nós estamos carregando o arquivo src/components/counter/index.js :)

E nesse arquivo é que está o componente CounterContainer :)

Ficou claro? :)

ghost commented 4 years ago

Que legal, @fdaciuk! Acho que não daria pra ter explicado melhor. Obrigado. 💯

fdaciuk commented 4 years ago

Show! Qualquer coisa, só avisar :)

ghost commented 4 years ago

Oi, @fdaciuk. Estava revisando e surgiram algumas dúvidas. A ordem abaixo é um bom entendimento do que acontece?

  1. A gente vai ao Redux para que crie um store. Ele é instruído sobre como queremos que atualize o estado e nos devolve um objeto que tem a "interface" de como podemos avisá-lo de quando devem acontecer as mudanças.

  2. No render do React, chamamos o Provider com o props store. Mais abaixo na renderização, o "esquema" (planejamento) de composição do connect já é mais um componente da cadeia de renderização, e, por isso, tem acesso ao store que foi passado ao Provider.

  3. A função (componente) CounterContainer, quando chamada dentro da função que o connect retornou, tem acesso ao que foi mapeado do estado, e por isso o Counter é renderizado com as mudanças.

  4. Toda vez que os dispatch são chamados nos eventos do Counter, o ciclo se repete.

É tudo. 😄

fdaciuk commented 4 years ago

É isso aí :)

Só a parte do dispatch: quando você chama essa função, os componentes que foram passados para a função connect serão re-renderizados, desde que o estado que esses componentes estejam consumindo mude :)