Atualizando estado dos componentes no React

Javascript

No post anterior eu falei sobre estados (state) nos componentes, como mantê-los e atualizá-los, porém, nesse post vou mostrar como podemos atualizar os estados de um componente no React com mais detalhes e exemplos, de uma forma um pouco mais profunda.

Utilizando o setState

Para atualizar o estado do componente, podemos utilizar a função setState de duas maneiras:

  1. Passando um novo estado parcial para ela.
  2. Passando uma função que recebe o estado atual e retorna um novo estado parcial.

Veja que temos diferentes maneiras de utilizar a função setState, mas, qual delas utilizar? Calma, já irei responder, antes eu quero falar sobre os estados parciais.

Estados parciais

A função setState recebe estados parciais, isso porque seria chato e tedioso toda hora ter que ficar concatenando o state por completo para depois realizar a modificação no mesmo, vamos ao exemplo:

state = {
    titulo : "Meu estado",
    subtitulo : "Parcial"
}

Dado o estado acima, se por um acaso precisarmos mudar o título, poderíamos simplesmente chamar a função setState:

this.setState({ titulo : "Meu titulo novo" })

Dessa maneira, o estado subtitulo ainda continuaria com o valor Parcial, porém, o estado titulo passaria agora a ter o valor igual á Meu titulo novo.

Se a função setState não fosse inteligente o suficiente para atualizar apenas o pedaço do objeto que passamos para ela, teríamos que fazer algo da seguinte maneira:

this.setState({ 
    ...this.state,
    titulo : "Meu titulo novo" 
})

Simplesmente pegamos o valor atual do state e passamos para o objeto, depois, é modificado apenas o pedaço que queremos, dessa maneira, ficou mais verboso o código, isso poderia ser facilmente esquecido de ser feito aumentando a chande de ocorrer um possível bug.

Estado parcial inexistente

Um detalhe curíoso: O que será que acontece se atualizarmos o estado passando um valor inexistente (até o momento) para ele? Imagine o exemplo seguinte estado:

state = {
    titulo : "Meu componente"
}

Nosso estado tem apenas um estado, no caso, o valor titulo.

Agora, por um acaso, em alguma função que estamos atualizando o título, acabamos sem querer, também inserindo um subtitulo, exemplo:

atualizarTitulo = () => {
    this.setState({
        titulo : "Novo titulo",
        subtitulo : "Agora tem subtitulo"
    })
}

O que será que acontece com a nossa state? Pois é, se você respondeu que agora ela também terá o valor de subtitulo, você acertou, podemos até fazer uma renderização condicional nesse caso:

render() {
    const { titulo, subtitulo } = this.state
    return (
        <Fragment>
            <h1>{ titulo }</h1>
            { subtitulo && <h2>{ subtitulo }</h2> }
        </Fragment>
    )
}

Dessa maneira, o h2 somente será renderizado quando houver a propriedade subtitulo com algum valor diferente de undefined e null.

Atualizando estado via objeto

Normalmente iremos atualizar o estado passando um objeto para ele, como já fizemos nos exemplos acima, por exemplo:

this.setState({ novo_estado : novo_valor })

A função setState irá setar/atualizar em nosso estado o valor referente as keys do objeto com seus respectivos valores.

Algo muito útil e geralmente é o que será mais utilizado no dia-á-dia, porém, também podemos atualizar nosso estado atráves de uma função.

Atualizando estado via função

Além de atualizar via objeto, também podemos passar uma função, onde, essa função recebe como parâmetro o estado atual e deve devolver o novo estado parcial, por exemplo:

this.setState(estadoAtual => {
    console.log(estadoAtual)
    return ({ 
        novo_estado : novo_valor
    })
});

Veja que o primeiro parâmetro é o estado atual (até o momento antes de atualizar o estado).

Se você está se perguntando quando e porque devemos utilizar dessa maneira, a resposta é muito simples: Quando seu novo estado depender do estado anterior (atual).

Por exemplo: Imagine que temos em nosso estado uma lista de alunos e queremos remover um determinado aluno, para evitar algo dessa maneira:

removerAluno = nome => {
    let { alunos } = this.state
    alunos = alunos.filter(aluno => aluno !== name)
    this.setState({ alunos })
}

Aqui, primeiro pegamos os alunos do nosso estado, depois, filtramos ele e passamos para a própria variável alunos, para depois chamar o setState. Esse código, poderia facilmente ser trocado por:

removerAluno = nome => {
    this.setState(({ alunos }) => ({
      alunos : alunos.filter(aluno => aluno !== name)
    }))
}

Dessa maneira o código fica mais organizado, pois, estamos acessando nosso estado apenas uma vez e não estamos manipulando ele diretamente.

Callback após atualizar o estado

Para ambas maneiras que podemos atualizar nosso estado, é possível (se necessário) passar uma função de callback para a setState como seu segundo parâmetro, portanto, a definição da função setState fica da seguinte maneira:

function setState(partialState, callback) {
    // implementação
}

Se você dúvida de mim, podemos ver diretamente no código fonte do React a declaração da função setState para a classe Component:

Função setState original do React

Essa função de callback é sempre bom para casos onde algo deve ser executado com o novo valor de state.

Obs: Lembrando que a função de callback será executado apenas e logo após ao estado ser atualizado.

Conclusão

Nesse post eu falei e tentei explicar um pouco o funcionamento da função setState para a classe Component, mostrei como podemos atualizar o estado do nosso componente, expliquei em qual ocasião uma maneira pode ser melhor que a outra e por fim vimos que também podemos passar uma função de callback que será executada logo após o estado do componente ser atualizado.

Se você gostou desse post e tem interesse em receber novidades por email, é muito fácil, se inscreve na newsletter através do formulário abaixo.

Matheus Castiglioni

Matheus Castiglioni

Apaixonado pelo mundo dos códigos e um eterno estudante, gosto de aprender e saber um pouco de tudo, aquela curiosidade de saber como tudo funciona, tento compartilhar o máximo de conhecimentos adquiridos e ajudar todos aqueles que sou capaz.

Post's Relacionados

Visualize outros post's relacionados ao mesmo assunto:

Trabalhando com eventos no JavaScript

Javascript
No post anterior eu falei sobre estados (state) nos componentes, como mantê-los e atualizá-los, porém, nesse post vou mostrar como podemos atualizar os estados de um componente no React com mais detalhes e exemplos, de uma forma um pouco mais profunda....
Continuar lendo

Referenciando componentes no React

Javascript
No post anterior eu falei sobre estados (state) nos componentes, como mantê-los e atualizá-los, porém, nesse post vou mostrar como podemos atualizar os estados de um componente no React com mais detalhes e exemplos, de uma forma um pouco mais profunda....
Continuar lendo

Mantendo estados de componentes no React com state

Javascript
No post anterior eu falei sobre estados (state) nos componentes, como mantê-los e atualizá-los, porém, nesse post vou mostrar como podemos atualizar os estados de um componente no React com mais detalhes e exemplos, de uma forma um pouco mais profunda....
Continuar lendo

String em JavaScript com aspas simples ou duplas?

Javascript
No post anterior eu falei sobre estados (state) nos componentes, como mantê-los e atualizá-los, porém, nesse post vou mostrar como podemos atualizar os estados de um componente no React com mais detalhes e exemplos, de uma forma um pouco mais profunda....
Continuar lendo

Listando tarefas com React

Javascript
No post anterior eu falei sobre estados (state) nos componentes, como mantê-los e atualizá-los, porém, nesse post vou mostrar como podemos atualizar os estados de um componente no React com mais detalhes e exemplos, de uma forma um pouco mais profunda....
Continuar lendo