Blog Formação DEV

Novidades do React 19

O React 19 chegou e neste artigo conheceremos algumas novidades que vêm junto com ele.
Novidades do React 19
Texto de: Marlliton Souza

Introdução

Recentemente, foi anunciado o React 19 RC, uma versão Release Candidate que traz várias melhorias e novidades para uma das tecnologias de desenvolvimento frontend mais populares do mercado, e neste artigo falaremos de algumas dessas novidades.

Ações (actions)

As actions nos permitem ouvir eventos disparados pelo usuário, seja um click, ou um envio de formulário e simplificam o gerenciamento de estados e mutação de dados que acontece em função desse evento.

Dessa forma podemos automatizar processos como lidar com estados pendentes e estados de erros, de forma mais eficiente. O que deixa nosso código mais limpo. Por exemplo, imagine que você está fazendo o envio de formulário de forma tradicional no React, provavelmente, você terá um código parecido com esse:

function Form() {
  const [nome, setNome] = useState("");
  const [erro, setErro] = useState(null);
  const [carregando, setCarregando] = useState(false);

  const submeter = async () => {
    setCarregando(true);
    const erro = await enviarNome(nome);
    setCarregando(false);
    if (erro) {
      setErro(erro);
      return;
    }
    redirect("/path");
  };

  return (
    <div>
      <input value={nome} onChange={valor => setNome(valor.target.value)} />
      <button onClick={submeter} disabled={carregando}>
        Enviar
      </button>
      {erro && <p>{erro}</p>}
    </div>
  );
} 

Com o uso das actions, podemos automatizar, por exemplo, o estado de carregamento da aplicação usando useTransition:

function Form() {
  const [nome, setNome] = useState("");
  const [erro, setErro] = useState(null);
  const [isPending, startTransition] = useTransition();

  const submeter = () => {
    startTransition(async () => {
      const erro = await enviarNome(nome);
      if (erro) {
        setErro(erro);
        return;
      } 
      redirect("/path");
    })
  };

  return (
    <div>
      <input value={nome} onChange={(event) => setNome(event.target.value)} />
      <button onClick={submeter} disabled={isPending}>
        Enviar
      </button>
      {erro && <p>{erro}</p>}
    </div>
  );
} 

Com o uso do useTransition não precisamos mais manipular estados de carregamento manualmente com o uso de estados, basta usarmos já que o isPending será true quando a transação começa e false automaticamente quando ela termina com erro ou sucesso. Isso permite que a interface se mantenha interativa mesmo enquanto os dados estiverem sendo alterados.

Novo hook useActionState

O React 19 também introduziu o suporte para o useActionState que é um hook que pode ser usado para gerenciar formulários automaticamente.

O useActionState aceita uma função, que é chamada de action (ação), e retorna uma ação encapsulada que pode ser passada para o seu formulário. Essa ação irá gerenciar os estados possíveis do form de uma forma simples, o que permite que possamos gerenciar estados de erro e carregamento com facilidade.

import { redirect } from "next/navigation";
import { useActionState } from "react";

export default function Form() {
  const [error, submitAction, isPending] = useActionState(
    async (estadoAnterior, formData) => {
      const error = await enviarNome(formData.get("nome"));
      if (error) {
        return error;
      }
      redirect("/path");
      return null;
    },
    null,
  );

  return (
    <form action={submitAction}>
      <input type="text" name="nome" />
      <button type="submit" disabled={isPending}>Enviar</button>
      {error && <p>{error}</p>}
    </form>
  );
} 

Nova API: use

De forma tradicional, sempre usamos estados (useState) e efeitos colaterais (useEffect) para lidar com requisições assíncronas. Usando a nova API use podemos descartar o uso de useState e useEffect para lidar com esse tipo de requisições.

Basta passar a promessa para o método use e ele mesmo se encarregará de fazer a suspensão dos componentes e quando o resultado da promessa chegar ele já se encarrega de “liberar” o uso dos dados que poderão ser renderizados em seguida.

import { Suspense, use } from "react";

function Posts({ promessa }: { promessa: Promise<string[]> }) {
  const res = use(promessa);
  return <div>{res.map(post => post)}</div>;
}

export default function Home() {
  const promessa = new Promise<string[]>(resolve => {
    setInterval(() => resolve(["Post 1", "Post 2", "Post 3", "Post 4"]), 2000);
  });

  return (
    <div>
      <Suspense fallback={<div>carregando...</div>}>
        <Posts promessa={promessa} />
      </Suspense>
    </div>
  );
} 

Também é possível ler contextos inteiros com essa nova API, o que dispensa o uso do hook useContext:

import { use } from "react";
import TemaContext from "./TemaContext";

export default function Home({ children }) {
  const tema = use(TemaContext);
  return (
    <div
      style={{
        color: tema.cor,
      }}
    >
      {children}
    </div>
  );
} 

Melhorias do React 19

Agora, você pode passar referencias (ref) usando as props, ou seja, não é mais necessário fazer uso do forwardRef. Antes, para fazermos uso das refs em componentes, nós faríamos assim:

const Input = forwardRef<HTMLInputElement, InputProps>(
    ({ className, children ...rest }, ref) => {
        
        return (
            <input ref={ref} className={className} {...rest}>{children}</input>
        )
    },
)

Input.displayName = 'Input'

//...
<Input ref={ref} /> 

Então, apesar da complexidade para iniciante de entender e utilizar o forwardRef tínhamos que declarar o displayName, caso contrário o React não saberia o nome do componente. Agora, basta passar a ref por props, como qualquer outra propriedade React:

function Input({placeholder, ref}) {
  return <input placeholder={placeholder} ref={ref} />
}

//...
<Input ref={ref} /> 

Contexto como provedor

Agora, não precisamos mais utilizar <Context.Provider> para criar provedores de contexto em nossa aplicação, basta envolver a aplicação com o contexto, sem precisar chamar o provider:

const TemaContext = createContext('');

function App({children}) {
  return (
    <TemaContext value="dark">
      {children}
    </TemaContext>
  );  
} 

Resumo

O React 19 trouxe muitas novidades, como a adição de novos hooks e melhorias na API, que nos ajudarão a criar aplicações mais leves e performáticas. Além das novidades abordadas neste artigo, existem várias outras melhorias e adições feitas ao React 19 que você pode conferir clicando aqui.

Sobre o autor
Cod3r

Cod3r

Com mais de 400 mil alunos, a Cod3r é uma das principais escolas de tecnologia do País. Um de seus produtos mais importantes é a Formação DEV, com objetivo de preparar os profissionais para o mercado.

Ótimo! Inscreveu-se com sucesso.

Bem-vindo de volta! Registou-se com sucesso.

Assinou com sucesso o Blog Formação DEV .

Sucesso! Verifique o seu e-mail para obter o link mágico para se inscrever.

As suas informações de pagamento foram atualizadas.

Seu pagamento não foi atualizado.