Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

A atualização do state.

No código abaixo, percebi que a atualização do state não é instantânea. Logando antes e depois do setState, a mudança não se dá no ato, mas parece aparecer após renderização da página, ou seja, após adicionar o 1 elemento, o state aparece zerado. Após adicionar o segundo elemento, o state contem 1 elemento, e assim por diante.

criarNota(titulo, texto){
    const novaNota = {titulo, texto};
    console.log("novaNota", novaNota);
    const novoArrayNotas = [...this.state.notas, novaNota];
    console.log("novoArrayNotas", novoArrayNotas);
    const novoEstado = {
      notas:novoArrayNotas
    }
    console.log("state antes", this.state);
    this.setState(novoEstado);
    console.log("state depois", this.state);
  }

Por que isso acontece?

Outra dúvida que tive foi com relação a alteração do state. Se utilizar um object novaNota:

 const novaNota = {titulo, texto};

o código funciona. Se alterar e utilizar um array:

 const novaNota = [titulo, texto];

ele não funciona.

Por quê isso acontece?

4 respostas

Fala ai Bruno, tudo bem? Vamos lá:

No código abaixo, percebi que a atualização do state não é instantânea

A atualização do estado é uma operação assíncrona, a gente não sabe quando ela vai ocorrer, pode ser rápida ou devagar.

o código funciona. Se alterar e utilizar um array:

Porque dessa forma você vai ter um array dentro de um array formando uma matriz, mas, você precisa de um array de objetos.

Espero ter ajudado.

solução!

Oi Bruno!

Realmente, o state não é atualizado imediatamente, a mudança ocorrerá somente quando o componente for renderizado novamente. Isso acontece porque tanto o state quanto o setState são imutáveis, ou seja, não é possível alterar o valor deles uma vez declarados. Quando você ver sobre os hooks, observe que eles são declarados como const. Isso é feito para que os objetos manipulados pelo React (componentes e seus states) não mudem e causem efeitos colaterais. Apesar de parecer que o state mudou, quando o componente é renderizado novamente, um novo state é criado, contendo o valor chamado pelo setState que causou a renderização.

Agora vamos para o seu código: Os console.log() que aparecem estão "atrasados" mas o state do componente está sim com os valores atualizados.

Vamos supor que o state comece como um array vazio. Quando criarNota() é chamado da primeira vez, uma nova nota é criada, depois ela é adicionada ao novoState. O primeiro console.log() printa o this.state atual que é nulo. O segundo também printará a mesma coisa, pois o this.state é imutável como dito acima, o seu valor só será atualizado na próxima renderização, que acontece pois setState é executado.

Quando a próxima renderização ocorre, this.state recebe o valor passado para o setState da renderização anterior, ou seja, o this.state recebe novoEstado que contém uma nota. Porém quando a função criaNota é executada, o primeiro console.log printa o estado atual, e o segundo a mesma coisa pelo motivo do parágrafo anterior. Uma nova renderização é causada pelo setState, um novo estado é criado e assim por diante.

Então apesar dos console.log estarem atrasados, o estado do componente está sim atualizado. Teste isso adicionando as seguintes linhas de código que utiliza o último item do array do state

<h1>{this.state.notas[this.state.notas.length - 1].titulo}</h1>
<p>{this.state.notas[this.state.notas.length - 1].texto}</p>

O código acima pode ajudar a entender sua segunda dúvida. Quando a linha a seguir é executada

const novoArrayNotas = [...this.state.notas, novaNota];

estamos adicionando um objeto com as propriedades titulo e texto ao array novoArrayNotas. Por ser um objeto, é possível acessar suas propriedades com a sintaxe objeto.propriedade, como nota.texto ou nota.titulo. Caso a novaNota fosse declarada como um array isso não seria possível, pois os elementos teriam que ser acessados com nota[0] e nota[1] e isso quebraria o código, pois o restante dos objetos teriam as propriedades texto e titulo mas o novaNota não. Ou seja, ao tentar executar o comando novaNota.titulo teriamos como retorno undefined.

Essas perguntas foram bem complicadas, então não se preocupe caso não entenda imediatamente. Caso surjam novas dúvidas ou você queira outra explicação, poste aqui!

Parabéns por ter feito essas reflexões! Elas são muito importantes para um bom aprendizado.

Espero ter ajudado.

Obrigado pelas respostas! Acho que a assincronicidade do método setState me confundiu, mas explicaram muito bem sobre os estados.

Magina Bruno, sempre que precisar não deixe de criar suas dúvidas.

Abraços e bons estudos.