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

Problema de atualização de uma string gravada no state

Pessoal, eu estou com um problema que já tive em outro projeto meu, que, apesar de aparecer simples eu não estou conseguindo arrumar.

Resumidamente, o valor do input é pego, atualizado no State e imprimido no console, porém o valor mostrado sempre está uma string "para trás", segue o exemplo:

O que foi escrito:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Console:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Com ou sem o atributo 'value' no input ou com algum valor inicial no useState('') o problema permanece.

Segue o código:

export default function Input({ label, placeholder }) {

  const [inputValue, setInputValue] = useState('');

  function aoEscrever(event) {
    setInputValue(event.target.value);
    console.log(inputValue);
  }

  return (
    <fieldset>
      <label>{label}</label>
      <input
        placeholder={placeholder}
        value={inputValue}
        onChange={aoEscrever}
        />
    </fieldset>
  );
}
5 respostas

Salve, Allan.

Isso acontece porque o setInputValue é assíncrono.

O console.log é executado antes que o estado, em si, seja atualizado.

Tudo bom Vinny?

Mas como que eu faria para consertar isso?

solução!

Você pode utilizar o hook useEffect para observar o valor do estado e reagir a isso.

Dessa forma:

export default function Input({ label, placeholder }) {

  const [inputValue, setInputValue] = useState('');

  function aoEscrever(event) {
    setInputValue(event.target.value);
  }

  useEffect(() => {
    console.log(inputValue)
  }, [inputValue])

  return (
    <fieldset>
      <label>{label}</label>
      <input
        placeholder={placeholder}
        value={inputValue}
        onChange={aoEscrever}
        />
    </fieldset>
  );
}

Se quiser conhecer mais o useEffect, aqui você consegue ver a documentanção dele.

Mas repara, Allan, que não tem nada "quebrado" no seu código.

Vou deixar aqui pra você também uma referência sobre síncrono e assíncrono, esse post da Ju Amoesei.

Mas beeem a grosso modo, o que acontece é o seguinte:

function aoEscrever(event) {
    setInputValue(event.target.value); // o JavaScript não vai esperar que esse código seja executado, ele chama a função e já parte pra próxima instrução
    console.log(inputValue); // quando essa linha é executada, o estado ainda não foi atualizado. por isso ele sempre fica com "uma letra a menos". porque ainda é o estado anterior.
  }

Ahh entendi tudo professor, muito obrigado pela luz! :)