Fique por dentro do que há de novo no React 18

React JS

Fique por dentro do que há de novo no React 18

O time do React lançou recentemente uma versão alpha do React 18. Esse lançamento é focado em experiência do usuário e em performance com melhorias internas de arquitetura e nesse artigo vou dar um overview das novidades que estão presentes nesse release. Lembrando que essas novas features não exigem grandes mudanças no código.

Automatic Batching

Vamos começar com a performance, nós temos grandes melhorias no Automatic Batching.

Veja o código abaixo:

function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    setCount(c => c + 1); // Does not re-render yet
    setFlag(f => !f); // Does not re-render yet
    // React will only re-render once at the end (that's batching!)
  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
    </div>
  );
}

O código acima exemplifica a atualização de 2 estados por uma função.

Antes do React 18, por padrão quando chamamos uma função que muda 2 estados como no exemplo, o React identifica que os estados estão próximos e faz somente uma renderização com os novos valores. Porém esse funcionamento está restrito a somente funções que não são assíncronas ou que não rodam dentro de um setTimeout, no React 18 isso será resolvido e está nova feature estará disponível para chamadas assíncronas.

E agora o mesmo exemplo com uma função assíncrona:

function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    fetchSomething().then(() => {
      // React 17 and earlier does NOT batch these because
      // they run *after* the event in a callback, not *during* it
      setCount(c => c + 1); // Causes a re-render
      setFlag(f => !f); // Causes a re-render
    });
  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
    </div>
  );
}

Essa nova feature traz grandes melhorias de performance quando lidamos com muitos estados em uma função assíncrona agrupadas em uma única renderização. Mas o melhor é que poderemos controlar o comportamento utilizando o flushSync(), os exemplos de utilização estão aqui.

Root API

No React a forma como criamos um nível Root no DOM e nele adicionamos um componente React, será descontinuada e agora teremos uma nova Root API.

Abaixo um exemplo com a forma antiga e com a nova:

import * as ReactDOM from 'react-dom';
import App from 'App';

const container = document.getElementById('app');

// Old
ReactDOM.render(<App />, container);
// New
const root = ReactDOM.createRoot(container);

root.render(<App />);

Outras coisas mudam com essa atualização, veja abaixo:

  • O render callback foi completamente removido;
  • O hydrate agora uma opção do createRoot;

Você pode ver alguns exemplos na WG thread.

Concurrent Rendering

Sem dúvida, uma das grandes atualizações do React 18 é o “concurrent mode” que agora é chamado de “concurrent rendering”.

Essa mudança de nome é importante, pois significa que podemos fazer uma adoção gradual dos novas “concurrent features”. Na prática isso permite adotar os novos recursos sem precisar reescrever o seu código.

Novas APIs

Com novos recursos, vêm novas APIs. No caso da renderização simultânea, todos eles são opcionais e cobrem coisas como transições de estado, atualizações de suspensão e novos hooks.

  • StartTransition

Imagine um input de uma busca onde o resultado precisa ser atualizado em tempo real, se você já fez algo semelhante notou que a UI sofre alguns pequenos travamentos quando o usuário está digitando. Isso ocorre porque para o React os componentes tem a mesma prioridade de atualização é por tanto ele aguardar o fluxo de renderização do componente acabar para atualizar a nova versão do input.

E se nós tivéssemos a possibilidade de escolher o que tem prioridade nesse fluxo de atualização. Essa nova API nos dá essa possibilidade de informar o que é urgente e precisa estar atualizado na tela, deixando outras coisas em segundo plano.

Abaixo um exemplo da nova API

import { startTransition } from 'react';


// Urgent: Show what was typed
setInputValue(input);

// Mark any state updates inside as transitions
startTransition(() => {
  // Transition: Show the results
  setSearchQuery(input);
});
  • useDeferredValue

Com o useDeferredValue, temos um novo hook que adia a atualização de partes que são menos importantes da nossa aplicação.

import { useDeferredValue } from "react";

// ...

const [text, setText] = useState("text");
const deferredText = useDeferredValue(text, { timeoutMs: 2000 });

// ...

O hook irá retornar uma versão atrasada do valor passado, que ficará “atrasado” em relação ao original até o tempo limite fornecido. Esse hook pode ser útil em situações que precisamos implementar comportamentos adiados baseados em estados complexos.

  • SuspenseList

Por último, há agora um novo componente de <SuspenseList /> para que possamos organizar a ordem dos componentes diretamente aninhados. Podemos usar <Suspense /> para vários componentes que retornam dados em momentos diferentes, mantendo os componentes importantes visíveis.

import { Suspense, SuspenseList } from "react";
const App = () => {
  return (
    <SuspenseList revealOrder="forwards">
      <Suspense fallback={"Loading..."}>
        <ProfilePicture id={1} />
      </Suspense>
      <Suspense fallback={"Loading..."}>
        <ProfilePicture id={2} />
      </Suspense>
      <Suspense fallback={"Loading..."}>
        <ProfilePicture id={3} />
      </Suspense>
    </SuspenseList>
  );
};
// ...

Mais informações sobre essa API podem ser encontradas em Work-In-Progress (WIP) documentation.

Streaming SSR

No Server Side Rendering tem tido bastante atenção por parte do time do React, além das melhorias mencionadas no Suspense, também temos grandes mudanças na arquitetura do SSR.

Essas melhorias irão permitir ter 2 novos recursos principais, o uso de <Suspense /> e React.lazy(), tudo isso junto com o streaming SSR de HTML renderizado e hidratação seletiva para iniciar a hidratar a aplicação o mais cedo possível.

SSR é um assunto muito complexo para abordar somente em um artigo e como muitas coisas estão acontecendo, sugiro que para uma visão adicional verifique a discussão no tópico do github, lá existe uma discussão detalhada sobre SSR, se você estiver interessado clique aqui.

Como instalar

Para obter a versão alpha do React 18, basta seguir os passos abaixo.

npm install react@alpha react-dom@alpha

Conclusão

Ainda vai levar um bom tempo para que a versão estável seja lançada, mas já é possível ver para onde o React está indo, não deixe de acessar o React WG no github. Lá existem discussões sobre vários recursos e todos os itens deste artigo foram retirados de lá.

https://github.com/reactwg/react-18

Espero que este artigo tenha ajudado você sobre o que vem por ai, obrigado pela atenção e não deixe de ler sobre outros temas que abordo no blog.

Explore mais