Articles

Compreender Reat ‘setState’

Reat components can, and often do, have state. Estado pode ser qualquer coisa, mas pense em coisas como se um usuário está logado ou não e exibindo o nome de usuário correto com base em que conta está ativa. Ou uma série de posts no blog. Ou se um modal está aberto ou não e qual aba dentro dele está ativo.

reaja components with state render UI based on that state. Quando o estado dos componentes muda, o mesmo acontece com a UI componente. Isso torna importante compreender quando e como mudar o estado do seu componente. No final deste tutorial, você deve saber como setState funciona, e ser capaz de evitar armadilhas comuns que muitos de nós atingir quando a aprendizagem reage.

o funcionamento de`setState () ‘

setState() é a única forma legítima de atualizar o estado após a configuração inicial do estado. Digamos que temos um componente de pesquisa e queremos exibir o termo de pesquisa que um usuário submete.

Aqui está a configuração:

import React, { Component } from 'react'class Search extends Component { constructor(props) { super(props) state = { searchTerm: '' } }}

Estamos passando uma seqüência vazia como um valor e, para actualizar o estado de searchTerm, temos que chamar setState().

setState({ searchTerm: event.target.value })

Aqui, estamos passando um objeto para setState(). O objeto contém a parte do Estado que queremos atualizar que, neste caso, é o valor de searchTerm. Reat pega este valor e funde-o no objeto que precisa dele. É uma espécie de como o Search componente pergunta o que ele deve usar para o valor de searchTerm e setState() responde com uma resposta.

isto é basicamente iniciar um processo que reage chama reconciliação. O processo de reconciliação é a forma como reagem atualiza o DOM, fazendo alterações ao componente com base na mudança de Estado. Quando o pedido para setState() é despoletado, Reat cria uma nova árvore contendo os elementos reativos no componente (juntamente com o estado atualizado). Esta árvore é usada para descobrir como o UI do componenteSearch deve mudar em resposta à mudança de Estado, comparando-o com os elementos da árvore anterior. Reat sabe quais as alterações a implementar e só actualizará as partes do DOM quando necessário. É por isso que a reacção é rápida.

isso soa muito, mas para resumir o fluxo:

  • Nós temos um componente de pesquisa que apresenta um termo de pesquisa
  • Que o termo de pesquisa é de momento vazio
  • O usuário envia um termo de pesquisa
  • o termo é capturado e armazenado por setState valor
  • a Reconciliação acontece e Reagir percebe a alteração no valor
  • Reagir instrui o componente de pesquisa para atualizar o valor e o termo de pesquisa é intercaladas

O processo de reconciliação não, necessariamente, de mudar toda árvore, exceto em uma situação onde a raiz da árvore é alterado como este:

// old<div> <Search /></div>// new<span> <Search /></span>

Todos <div> tags tornam <span> tags e toda a componente árvore vai ser atualizado como resultado.

A regra geral é nunca mutar o estado diretamente. Utilizar sempre setState() para mudar de Estado. Modificar o estado diretamente, como o excerto abaixo não fará com que o componente volte a renderizar.

// do not do thisthis.state = { searchTerm: event.target.value}

passando uma função para `setState ()`

para demonstrar mais esta ideia, vamos criar um contador simples que aumenta e diminui ao clicar.

See the Pen setState Pen by Kingsley Silas Chijioke (@kinsomicrote) on CodePen.

let’s register the component and definite the markup for the UI:

class App extends React.Component {state = { count: 0 }handleIncrement = () => { this.setState({ count: this.state.count + 1 })}handleDecrement = () => { this.setState({ count: this.state.count - 1 })} render() { return ( <div> <div> {this.state.count} </div> <button onClick={this.handleIncrement}>Increment by 1</button> <button onClick={this.handleDecrement}>Decrement by 1</button> </div> ) }}

neste ponto, o contador simplesmente aumenta ou diminui a contagem em 1 em cada clique. mas e se quiséssemos aumentar ou diminuir em 3? Poderíamos tentar chamar setState() três vezes o handleDecrement e handleIncrement funções como este:

handleIncrement = () => { this.setState({ count: this.state.count + 1 }) this.setState({ count: this.state.count + 1 }) this.setState({ count: this.state.count + 1 })}handleDecrement = () => { this.setState({ count: this.state.count - 1 }) this.setState({ count: this.state.count - 1 }) this.setState({ count: this.state.count - 1 })}

Se estiver a codificar em casa, poderá ficar surpreendido por ver que isso não funciona.

O trecho de código acima é equivalente a:

Object.assign( {}, { count: this.state.count + 1 }, { count: this.state.count + 1 }, { count: this.state.count + 1 },)

Object.assign() é usado para copiar dados de um objecto de origem de um objeto de destino. Se os dados que estão sendo copiados da fonte para o alvo todos têm as mesmas chaves, como no nosso exemplo, o último objeto ganha. Aqui está uma versão mais simples de como Object.assign() funciona;

let count = 3const object = Object.assign({}, {count: count + 1}, {count: count + 2}, {count: count + 3});console.log(object);// output: Object { count: 6 }

assim, em vez de a chamada acontecer três vezes, acontece apenas uma vez. Isto pode ser corrigido passando uma função para setState(). Assim como você passa objetos para setState(), Você também pode passar funções, e essa é a maneira de sair da situação acima.

Se editarmos a função handleIncrement para ficar assim:

handleIncrement = () => { this.setState((prevState) => ({ count: prevState.count + 1 })) this.setState((prevState) => ({ count: prevState.count + 1 })) this.setState((prevState) => ({ count: prevState.count + 1 }))}

…podemos agora contar de incrementos três vezes com um clique.

neste caso, em vez de se fundir, reaja filas de espera da função na ordem em que são feitas e atualiza as de estado inteiro que é feito. Isto atualiza o estado de contagem para 3 em vez de 1.

acesse o estado anterior usando o Updater

quando construir aplicações Reat, há momentos em que você vai querer calcular o estado baseado no estado anterior do componente. Você nem sempre pode confiar em this.state para manter o estado correto imediatamente após chamar setState(), pois é sempre igual ao Estado representado na tela. vamos voltar ao nosso contra-exemplo para ver como isto funciona. Digamos que temos uma função que decreta a nossa contagem por 1. Esta função parece-se com esta:

changeCount = () => { this.setState({ count: this.state.count - 1})}

o que queremos é a capacidade de decremento por 3. A função changeCount() é chamada três vezes em uma função que lida com o evento click, assim.

handleDecrement = () => { this.changeCount() this.changeCount() this.changeCount()}

cada vez que o botão para decrementar é clicado, a contagem irá decrement por 1 em vez de 3. Isto porque o this.state.count não é atualizado até que o componente tenha sido re-renderizado. A solução é usar um updater. Um updater lhe permite acessar o estado atual e colocá-lo a usar imediatamente para atualizar outros itens. Assim, a função changeCount() será assim.

changeCount = () => { this.setState((prevState) => { return { count: prevState.count - 1} })}

Now we are not depending on the result ofthis.state. Os estados de count são construídos uns sobre os outros para que possamos acessar o estado correto que muda com cada chamada parachangeCount().

setState()deve ser tratado de forma assíncrona — por outras palavras, nem sempre espere que o estado tenha mudado depois de chamarsetState().

Quebra automática

Ao trabalhar com setState(), estas são as principais coisas que você deve saber:

  • Atualização para o estado de um componente deve ser feito usando setState()
  • Você pode passar um objeto ou uma função de setState()
  • Passar uma função quando você pode atualizar o estado várias vezes
  • não dependem desta.declare imediatamente após chamar setState() e faça uso da função updater em vez disso.