Closed pamplonapaulo closed 4 years ago
Oi @pamplonapaulo! Sua dúvida é completamente válida sim :) Eu acredito que falei na aula, mas vou tentar explicar de uma forma que acho que pode ficar mais fácil de entender: quando você clica em um checkbox que não tenha seu estado controlado pelo React, o que vemos é:
Mas quando o estado de checked
desse checkbox é controlado pelo React, tem uma passo a mais no meio disso tudo. O que acontece é:
onClick
desse checkbox é disparado;e.target.checked
vai ser true
;e.target.checked
, aí sim nós atualizamos o estado do componente React que vai definir se o checkbox é "checked" ou "unchecked". Se ele estava "unchecked", e nossa intenção é que ele fique "checked", por conta do clique, nós alteramos o estado de "unchecked" para o valor de e.target.checked
(que vai ser true
);Deu pra sacar até aqui?
Levando isso em consideração, quando nós temos todos os sabores já selecionados, e clicamos para que um sabor fique "unchecked" (ou e.target.checked = false
), esse valor chega na nossa função, handler do evento, e pelo valor de e.target.checked
nós sabemos se aquele sabor está sendo "checked" ou "unchecked", antes mesmo de fazer a mudança visual (que só acontece com a alteração do estado).
Deu pra entender como isso funciona? :)
Fala mestre @fdaciuk !
Depois de ler a sua resposta eu ainda precisava dar uma conferida no código.
Como a gente escreve "e.target" eu achei que estivéssemos olhando diretamente no DOM, não no state.
Acabo de checar que, como você disse, é do state que estamos pegando a informação:
onChange={handleChangeCheckbox(pizza.id)}
Se fosse JS puro manipulando o DOM, então o elemento input eu esperaria que já tivesse a propriedade checked, sem qualquer delay. Faz sentido pra você ou eu to me confundindo mais? rs
Acho que preciso estudar mais os states e seus traços de async, para não ser surpreendido e ter problemas no futuro.
Obrigado mais uma vez!
Um abraço!
Acho que continuo falando bobagem. Não é state, é apenas um objeto pizzaFlavours.
Eu não entendo como console.log(e.target.checked) retorna true quando está não checked e retorna false quando está checked. kkk
Eu acabei de inspecionar o DOM aqui no Chrome e em nenhuma situação os inputs type='checkbox' ficam com o atributo 'checked'.
Onde essa informação é guardada? rsrsrs
Oi @pamplonapaulo! Vamos lá:
Como a gente escreve "e.target" eu achei que estivéssemos olhando diretamente no DOM, não no state. Sim, estamos falando do DOM mesmo. Quando um evento é disparado, através do objeto de eventos nós temos acesso ao que aconteceu no momento em que o evento foi disparado.
Nesse caso, o e.target
se refere à qual checkbox disparou o evento, e o e.target.checked
é o estado que estamos tentando atribuir para esse elemento.
O estado só não é atribuído na hora porque o valor final dele vem do React (ou do JS), não diretamente do resultado de e.target.checked
.
E por não ser atribuído na hora, é aí que conseguimos validar se o checkbox está tentando ser "checked" ou "unchecked", e antes disso acontecer, nós tomamos as devidas precauções :)
Deu pra entender? :)
Mestre, eu acho que minha cabeça deu um nó por não me atentar que onChange é diferente de onClick!!
É, é isso. Mas agora eu fico analisando o comportamento diferente dessa input tag, se é que podemos chamar de input tag. Parece se comportar de uma forma BEM diferente do que estava acostumado no DOM normal sem React.
O que faz exatamente o trigger do onChange? O que mudou de fato para acionar o onChange?
Porque parece ter sido um mero clique. Mesmo se a gente devolve o display block para esse input, para olhar com os olhos o comportamento do checked, vemos que ele obedece totalmente a regra do nosso código. Ele só marca e desmarca nas condições que nós demos.
Então se o click não resulta num change, o que deu o trigger no onChange? O atributo checked nunca surge na tag no DOM, em nenhuma situação. O que está de fato changing?
A regra do código só se dá dentro da própria onChange. Está lindo, mas tentando dissecar isso eu não entendo como ele visualmente não muda para checked/unchecked e, (removendo o display: none), depois da regra na função, retorna para aquilo que programamos. Ou será que isso tudo acontece porém na velocidade da luz e não podemos enxergar? rs
O Label, ao receber o click, promove o change do Input. Certo? E o change do Input aciona a função que escrevemos, que organiza as coisas no nosso state de array checkboxes. E seria a própria função que fizemos que, em um relâmpago, anula ou valida o change? O change pode ser trigged mesmo antes da confirmação de que haverá de fato o change?
Falei muito e acho que confundi você. Grosso modo, eu não entendo o onChange do input rodar quando nada muda, só por efeito do clique na label.
"The onchange event occurs when the value of an element has been changed." https://www.w3schools.com/jsref/event_onchange.asp
Mas sinceramente não quero te prender com isso. Depois a ficha vai cair rsrs...
@fdaciuk
haha! Sem crise, vamos lá :)
No caso do checkbox, os eventos de click e change fazem praticamente a mesma coisa. Acho que o que você está confundindo é que: você deve estar pensando que o evento onChange
só é disparado quando o elemento muda VISUALMENTE. Mas não, o que muda é o objeto desse evento no DOM.
Lembre-se que o DOM é uma API para manipular elementos HTML em tela. O checkbox (elemento da tela) é diferente do objeto do DOM.
Quando manipulamos o DOM através da API DOM, com JS (ou com React, o resultado é o mesmo), o evento de onChange
dispara quando existe a intenção de mudar o elemento da tela. Na tela não muda nada quando você clica no checkbox, apenas no objeto do DOM.
Com o objeto do DOM em mãos, ANTES DE MUDAR QUALQUER COISA NA TELA, o evento onChange
dispara, pois houve a intenção da mudança do estado, de "checked" para "unchecked" (ou vice-versa).
Então, antes de mudar em tela, nós validamos a informação, e fazemos o que precisa ser feito, para só então fazer a atualização do estado do elemento em tela.
Um exemplo bem bobo: esqueça React por alguns minutos, e um checkbox em um arquivo index.html
:
<input type="checkbox" />
No HTML mesmo, coloque um código JS para manipular o evento de "change" (ou "click", tanto faz) desse elemento:
const checkbox = document.querySelector('input')
checkbox.addEventListener('change', (e) => {
alert(`O novo estado para o checkbox após essa mensagem sumir vai ser ${e.target.checked}`)
})
Perceba que o estado do checkbox não vai mudar até que o alert
saia da tela. Mas veja que, quando o evento dispara, nós já temos, em e.target.checked
, o novo valor do estado que esse checkbox vai receber.
Então quando o evento dispara, ainda nada é alterado em tela. Há somente uma intenção de mudança. Depois que o evento dispara, aí sim o valor do checkbox pode se alterado :)
Testa aí e me diz se assim fica mais claro de entender :)
"Perceba que o estado do checkbox não vai mudar até que o alert saia da tela. Mas veja que, quando o evento dispara, nós já temos, em e.target.checked, o novo valor do estado que esse checkbox vai receber."
ô loko mano. Então tá bom! Agora faz todo o sentido.
Me perdoe alugar você com essa questão num domingo! kkk Eu estava realmente cismado com essa ordem das coisas. Agora entendi. Acho estranho que se dê nessa ordem, que o "e.target.checked" já nos entregue o resultado da ação antes dela ser totalmente concluída, mesmo com ação em suspense/pausada como no caso desse alert() na tela, mas soluciona o meu estranhamento. Eu tendo a crer que faria mais sentido se nos retornasse o estado prévio, antes da conclusão do que fora acionado.
Muito grato pela super aula!! :)
Então, o ideal é sempre pensar no seguinte: eventos acontecem sempre quando há a intenção de alguma ação. Imagine o caso, por exemplo, de um formulário: você quer que, ao submeter um formulário, antes dele de fato ser submetido, verificar se todos os campos estão ok, para só depois fazer a submissão dos dados.
Se o evento onSubmit
de um formulário disparar depois que os dados já foram submetidos, como você teria acesso aos campos, para validá-los?
Por isso, quando o evento onSubmit
dispara, e você quer validar os dados, você usa o e.preventDefault()
, que previne a ação padrão que esse evento faria (no caso, a submissão dos dados do form), e então faz o que quer antes da ação real acontecer de fato.
Todo evento é sempre uma intenção de algo acontecer. Se o evento disparar depois que a ação já aconteceu, não faz muito sentido ter os manipuladores de evento, concorda? :)
Sim, tenho que concordar! Olhando dessa forma realmente faz todo sentido. Essa questão da "intenção" da ação vai me ajudar a memorizar esse aprendizado. Vou me lembrar dessa conversa pra sempre! rs
Muito grato, prof.! Valeu mesmo!! :)
Show de bola meu caro! Qualquer dúvida, só avisar :D
Fala mestre @fdaciuk . Tudo bem?
Primeiramente, achei maravilhosa a aula. Me dei conta que nunca havia usado (nos meus projetos) o Object.keys (ou values, ou entries). E o refactoring do filter(Boolean) achei incrível.
Aula linda e tal, mas no fim fiquei muito encucado. A gente estabelece o limite conforme o tamanho da pizza e, pra fechar, fica faltando só permitir a remoção da seleção caso o user tenha atingido o limite. E então a gente finaliza a condition com:
O que eu estranho é que quando o user clica num sabor selecionado, isto é quando o user clica num target checked, o nosso handle leia como false. E quando clica num sabor desselecionado, isto é, um target unchecked, tenhamos então checked === true.
Caramba. Não era para ser o oposto?
O e.target.checked é true quando não está selecionado? E false quando está selecionado? Eu achava que fosse o contrário.
Tentei jogar um setTimeout para entender, ver se há algo mais acontecendo, mas não consegui ler o e.target dentro desse timeout. Fiquei estudando isso por um tempo, então resolvi vir aqui te perguntar.
Eu tô ficando maluco? kkk Ou minha dúvida faz algum sentido?
Grande abraço!