Sobes.tech
Junior

Como alterar corretamente o estado dos componentes no React?

sobes.tech IA

Resposta da IA

A alteração de estado no React ocorre através do método setState para componentes de classe ou usando o hook useState para componentes funcionais.

Componentes de classe:

// Importamos React
import React, { Component } from 'react';

// Criamos um componente de classe
class MyComponent extends Component {
  // Inicializamos o estado
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  // Método para alterar o estado
  incrementCount = () => {
    // Usamos setState
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <p>Contador: {this.state.count}</p>
        <button onClick={this.incrementCount}>Incrementar</button>
      </div>
    );
  }
}

// Exportamos o componente
export default MyComponent;
  • setState é assíncrono.
  • setState combina o novo estado com o atual (shallow merge).
  • setState pode aceitar uma função que retorna um novo estado baseado no anterior:
// Método para alterar o estado usando uma função
incrementCountFunction = () => {
  this.setState((prevState) => ({
    count: prevState.count + 1
  }));
};

Componentes funcionais (usando useState):

// Importamos React e useState
import React, { useState } from 'react';

// Criamos um componente funcional
function MyFunctionComponent() {
  // Inicializamos o estado com useState
  const [count, setCount] = useState(0); // [estado atual, função para atualizar]

  // Função para alterar o estado
  const incrementCount = () => {
    // Usamos a função para atualizar o estado
    setCount(count + 1);
  };

  return (
    <div>
      <p>Contador: {count}</p>
      <button onClick={incrementCount}>Incrementar</button>
    </div>
  );
}

// Exportamos o componente
export default MyFunctionComponent;
  • useState retorna um array de dois elementos: o estado atual e a função para atualizá-lo.
  • A função de atualização de estado, retornada por useState, substitui o estado atual, não o combina.
  • Pode-se passar uma função para a função de atualização se o novo estado depender do anterior:
// Função para alterar o estado usando uma função
const incrementCountFunction = () => {
  setCount(prevCount => prevCount + 1);
};

Pontos importantes ao alterar o estado:

  • Não modifique o estado diretamente: Nunca atribua um novo valor à propriedade state diretamente (por exemplo, this.state.count = 5 ou count = 5). React não detectará essa mudança e o componente não será rerenderizado.
  • Alteração de objetos e arrays: Ao modificar objetos ou arrays no estado, crie sempre novas cópias. React compara referências de objetos/arrays, e se a referência não mudar, React assume que os dados não mudaram e não rerenderiza.
// Alteração de objeto em componente de classe
this.setState(prevState => ({
  user: {
    ...prevState.user, // Copiando as propriedades antigas
    name: 'Novo nome' // Atualizando a propriedade necessária
  }
}));

// Alteração de array em componente funcional
setItems(prevItems => [...prevItems, 'Novo elemento']); // Adiciona um novo elemento
  • Assincronidade de setState: Se precisar executar uma ação após o estado ser atualizado e o componente rerenderizar, use o segundo argumento de setState (função de callback) ou o hook useEffect em componentes funcionais.
// Callback em setState
this.setState({ count: this.state.count + 1 }, () => {
  console.log('Estado atualizado!');
});
// useEffect para reagir à mudança de estado
useEffect(() => {
  console.log('O estado count mudou:', count);
}, [count]); // Dependência: o hook será acionado ao mudar count

Comparação de métodos:

Característica Componente de classe (setState) Componente funcional (useState)
Sintaxe Método this.setState(newState[, callback]) Hook const [state, setState] = useState(initialState)
União/Substituição Combina o novo estado com o atual (shallow merge) Substitui o estado atual pelo novo
Assincronia Assíncrono A função de atualização é assíncrona quando chamada de manipuladores de eventos, mas síncrona na fase de render do React
Dependência do estado anterior Passar uma função para setState: this.setState(prevState => ({...})) Passar uma função para a função de atualização: setState(prev => ({...}))