Hook de Otimização de Desempenho useTransition no React

O hook de otimização de desempenho useTransition nos permite atualizar estados sem bloquear a interface gráfica.

Com este hook, podemos atribuir uma prioridade baixa à atualização de um determinado estado, o que permitirá que a atualização de outros estados tenha alta prioridade e seja executada sem atrasos.

Como exemplo, podemos citar a filtragem de uma lista suspensa de produtos conforme o usuário digita caracteres no campo de pesquisa. Claro, a própria lista pode ser exibida com algum atraso, mas nós não gostaríamos que os caracteres fossem digitados no campo de pesquisa com atraso.

Vamos ver como, nessas situações, o hook useTransition pode nos ajudar. Suponha que temos um trecho de código do componente principal. Vamos analisá-lo:

App.jsximport { useTransition } from 'react';
import { useState } from 'react';

function App() {
  const [isPending, startTransition] = useTransition();
  const [filterTerm, setFilterTerm] = useState('');
  
  const filteredProducts = filterProducts(filterTerm);
  
  function updateFilterHandler(event) {
    startTransition(() => {
      setFilterTerm(event.target.value);
    });
  }
 
  return (
    <div>
      <input type="text" onChange={updateFilterHandler} />
      <ProductList products={filteredProducts} />
    </div>
  );
}

Aqui vemos duas variáveis para o useTransition. A variável isPending contém um valor booleano e indica se o processo de atualização foi concluído, e a função startTransition é que permite reduzir a prioridade da atualização:

App.jsxconst [isPending, startTransition] = useTransition();

Também temos o estado filterTerm, onde a expressão digitada no campo de entrada é armazenada, e a função setFilterTerm para defini-lo:

App.jsxconst [filterTerm, setFilterTerm] = useState('');

Ao digitar caracteres no input, a função updateFilterHandler é chamada a cada vez, onde a atualização do filterTerm ocorre. É aqui que aplicamos nosso hook useTransition, envolvendo a função de definição setFilterTerm em startTransition da seguinte forma:

App.jsxfunction updateFilterHandler(event) {
  startTransition(() => {
    setFilterTerm(event.target.value);
  });
}

Dessa forma, definimos uma prioridade baixa para a atualização do estado filterTerm e nosso campo de entrada permanecerá responsivo.

Usando a variável isPending, podemos mostrar ao usuário que a atualização da lista ainda está em andamento. Vamos exibir essa informação abaixo do campo de entrada, enquanto a lista está sendo atualizada:

App.jsxreturn (
  <div>
    <input type="text" onChange={updateFilterHandler} />
    {isPending && <p>atualizando ...</p>}
    <ProductList products={filteredProducts} />
  </div>
);