Estado e Ciclo de Vida
Esta página apresenta o conceito de estado e ciclo de vida em um componente React. Você pode encontrar uma referência detalhada da API de componente aqui.
Considere o exemplo do relógio de uma das seções anteriores. Em Elementos de Renderização, nós aprendemos apenas uma maneira de atualizar a UI. Nós chamamos ReactDOM.render() para mudar a saída renderizada.
function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(    element,    document.getElementById('root')  );}
setInterval(tick, 1000);Esta seção, aprenderemos como tornar o componente Clock verdadeiramente reutilizável e encapsulado. Ele irá configurar seu próprio temporizador e se atualizar a cada segundo.
Podemos começar encapsulando como o relógio parece:
function Clock(props) {
  return (
    <div>      <h1>Hello, world!</h1>      <h2>It is {props.date.toLocaleTimeString()}.</h2>    </div>  );
}
function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,    document.getElementById('root')
  );
}
setInterval(tick, 1000);No entanto, falta um requisito crucial: o fato de que o Clock configura um temporizador e atualiza a UI a cada segundo deve ser um detalhe de implementação do Clock.
Idealmente, queremos escrever isto uma vez e ter o Clock se atualizando:
ReactDOM.render(
  <Clock />,  document.getElementById('root')
);Para implementá-lo, precisamos adicionar um “state” ao componente Clock.
O state do componente é similar as props, mas é privado e totalmente controlado pelo componente.
Convertendo uma Função para uma Classe
Você pode converter um componente de função como Clock em uma classe em cinco etapas:
- Criar uma classe ES6, com o mesmo nome, estendendo 
React.component. - Adicionar um único método vazio chamado 
render(). - Mova o corpo da função para o método 
render(). - Substitua 
propsporthis.propsno corpo derender(). - Exclua a declaração da função vazia restante.
 
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}Clock agora é definido como uma classe em vez de uma função.
O método render será chamado toda vez que uma atualização acontecer, mas enquanto renderizarmos <Clock> no mesmo nó DOM, apenas uma única instância da classe Clock será usada. Isso nos permite usar recursos adicionais, como o estado local e os métodos de ciclo de vida.
Adicionando Estado Local a uma Classe
Vamos mover a date da props para o state em três passos:
- Substitua 
this.props.dateporthis.state.dateno métodorender(): 
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>      </div>
    );
  }
}- Adicione um construtor na classe que atribui a data inicial no 
this.state: 
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}Note como nós passamos props para o construtor:
  constructor(props) {
    super(props);    this.state = {date: new Date()};
  }Componentes de classes devem sempre chamar o construtor com props.
- Remova a props 
datedo elemento<Clock />: 
ReactDOM.render(
  <Clock />,  document.getElementById('root')
);Mais tarde, adicionaremos o código do temporizador de volta ao próprio componente.
O Resultado se parece com:
class Clock extends React.Component {
  constructor(props) {    super(props);    this.state = {date: new Date()};  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>      </div>
    );
  }
}
ReactDOM.render(
  <Clock />,  document.getElementById('root')
);Em seguida, faremos a configuração do próprio temporizador e atualizaremos a cada segundo.
Adicionando Métodos de Ciclo de Vida a Classe
Em aplicações com muitos componentes, é muito importante limpar os recursos utilizados pelos componentes quando eles são destruídos.
Queremos configurar um temporizador sempre que o Clock é renderizado para o DOM pela primeira vez. Isso é chamado de “mounting” no React.
Nós também queremos limpar o temporizador sempre que o DOM produzido pelo Clock for removido. Isso é chamado de “unmounting” no React.
Podemos declarar métodos especiais no componente de classe para executar algum código quando um componente é montado e desmontado:
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {  }
  componentWillUnmount() {  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}Estes métodos são chamados de “métodos de ciclo de vida”.
O método componentDidMount() é executado depois que a saída do componente é renderizada no DOM. Este é um bom lugar para configurar um temporizador:
  componentDidMount() {
    this.timerID = setInterval(      () => this.tick(),      1000    );  }Note como nós salvamos o ID do temporizador em this (this.timerID).
Enquanto this.props é configurado pelo próprio React e this.state tem um significado especial, você está livre para adicionar campos adicionais à classe manualmente se precisar armazenar algo que não participe do fluxo de dados (como um ID do temporizador)
Vamos derrubar o temporizador no método do ciclo de vida componentWillUnmount():
  componentWillUnmount() {
    clearInterval(this.timerID);  }Finalmente, vamos implementar um  método chamado tick() que o componente Clock executará a cada segundo.
Ele usará this.setState() para agendar atualizações para o estado local do componente:
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
  componentWillUnmount() {
    clearInterval(this.timerID);
  }
  tick() {    this.setState({      date: new Date()    });  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);Agora o relógio bate a cada segundo.
Vamos recapitular rapidamente o que está acontencendo e a ordem na qual os métodos são chamados:
- Quando 
<Clock />é passado paraReactDOM.render(), o React chama o construtor do componenteClock. ComoClockprecisa exibir a hora atual, ele inicializathis.statecom um objeto incluindo a hora atual. Mais tarde, atualizaremos este state. - React chama então o método 
render()do componenteClock. É assim que o React aprende o que deve ser exibido na tela. React em seguida, atualiza o DOM para coincidir com a saída de renderização doClock. - Quando a saída do 
Clocké inserida no DOM, o React chama o método do ciclo de vidacomponentDidMount(). Dentro dele, o componenteClockpede ao navegador para configurar um temporizador para chamar o métodotick()do componente uma vez por segundo. - A cada segundo o navegador chama o método 
tick(). Dentro dele, o componenteClockagenda uma atualização de UI chamandosetState()com um objeto contendo a hora atual. Graças à chamadasetState(), o métodorender()será diferente e, portanto, a saída de renderização incluirá a hora atualizada. React atualiza o DOM de acordo. - Se o componente 
Clockfor removido do DOM, o React chama o método do ciclo de vidacomponentWillUnmount()para que o temporizador seja interrompido. 
Usando o State Corretamente
Existem três coisas que você deve saber sobre setState().
Não Modifique o State Diretamente
Por exemplo, isso não renderizará novamente o componente:
// Errado
this.state.comment = 'Hello';Em vez disso, use setState():
// Correto
this.setState({comment: 'Hello'});O único lugar onde você pode atribuir this.state é o construtor.
Atualizações de State Podem Ser Assíncronas
O React pode agrupar várias chamadas setState() em uma única atualização para desempenho.
Como this.props e this.state podem ser atualizados de forma assíncrona, você não deve confiar em seus valores para calcular o próximo state.
Por exemplo, esse código pode falhar ao atualizar o contador:
// Errado
this.setState({
  counter: this.state.counter + this.props.increment,
});Para consertá-lo, use uma segunda forma de setState() que aceite uma função ao invés de um objeto. Essa função receberá o state anterior como o primeiro argumento e as props no momento em que a atualização for aplicada como o segundo argumento:
// Correto
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));Usamos uma arrow function acima, mas também funciona com funções regulares:
// Correto
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});Atualizações de State São Mescladas
Quando você chama setState(), o React mescla o objeto que você fornece ao state atual.
Por exemplo: seu state pode conter várias variáveis independentes:
  constructor(props) {
    super(props);
    this.state = {
      posts: [],      comments: []    };
  }Então você pode atualizá-los independentemente com chamadas separadas do setState():
  componentDidMount() {
    fetchPosts().then(response => {
      this.setState({
        posts: response.posts      });
    });
    fetchComments().then(response => {
      this.setState({
        comments: response.comments      });
    });
  }O merge é superficial, então this.setState({comments}) deixa this.state.posts intacto, mas substitui completamente this.state.comments
Os Dados Fluem para Baixo
Nem componentes pai ou filho podem saber se um determinado componente é stateful ou stateless, e não devem se importar se ele é definido por uma função ou classe.
É por isso que o state é geralmente chamado de local ou encapsulado. Não é acessível a nenhum componente que não seja o que o possui e o define.
Um componente pode escolher passar seu state como props para seus componentes filhos:
<FormattedDate date={this.state.date} />O componente FormattedDate receberia o date em seus objetos e não saberia se ele veio do state de Clock, das props do Clock, ou se foi digitado manualmente:
function FormattedDate(props) {
  return <h2>It is {props.date.toLocaleTimeString()}.</h2>;
}Isso é comumente chamado de fluxo de dados “top-down” ou “unidirecional”. Qualquer state é sempre de propriedade de algum componente específico, e qualquer dado ou interface do usuário derivado desse state só pode afetar os componentes “abaixo” deles na árvore.
Se você imaginar uma árvore de componentes como uma cascata de props, o state de cada componente é como uma fonte de água adicional que o une em um ponto arbitrário, mas também flui para baixo.
Para mostrar que todos os componentes estão isolados, podemos criar um componente App que renderiza três <Clock>s:
function App() {
  return (
    <div>
      <Clock />      <Clock />      <Clock />    </div>
  );
}
ReactDOM.render(
  <App />,
  document.getElementById('root')
);Cada Clock configura seu próprio temporizador e atualiza de forma independente.
Nos apps React, se um componente é stateful ou stateless é considerado um detalhe de implementação do componente que pode mudar com o tempo. Você pode usar componentes sem state dentro de componentes com state e vice-versa.