Como atualizar para o React 18

0
26


O React 18 evolui a popular estrutura de componentes JavaScript com novos recursos construídos em torno de renderização e suspense simultâneos. Ele promete melhor desempenho, mais recursos e uma experiência de desenvolvedor aprimorada para aplicativos que fazem a troca.

Neste artigo, mostraremos como atualizar suas bases de código existentes para o React 18. Observe que este guia é apenas uma visão geral das alterações mais aplicáveis. A migração deve ser bastante fácil para pequenos projetos que já seguem as melhores práticas do React; grandes conjuntos de componentes complexos podem levar a alguns problemas, que detalharemos a seguir.

Instalando o React 18

Antes de fazer qualquer outra coisa, use npm para atualizar a dependência React do seu projeto para v18:

$ npm install [email protected] [email protected]

A nova versão não possui tecnicamente nenhuma incompatibilidade com as versões anteriores. Novos recursos são ativados voluntariamente. Como você ainda não alterou nenhum código, poderá iniciar seu aplicativo e assisti-lo renderizar corretamente. Seu projeto será executado com seu comportamento React 17 existente.

$ npm start

Habilitando recursos do React 18: a nova API raiz

Usar o React 18 sem nenhuma alteração na base de código causará um efeito colateral: você verá um aviso no console do navegador toda vez que seu aplicativo for montado no modo de desenvolvimento.

Final Result: React session storage
ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17.

Essa mensagem de descontinuação pode ser ignorada com segurança se você não estiver pronto para atualizar seu projeto. Quando você deseja adotar os recursos do React 18, você precisa fazer a mudança descrita. O velho ReactDOM.render() A função foi substituída por uma nova API raiz que é mais orientada a objetos. Além de melhorar a usabilidade, também permite o sistema de renderização simultânea que alimenta todos os novos recursos de título.

dentro de você index.js qualquer app.js arquivo, procure por linhas semelhantes a estas:

import App from "./App.js";
import ReactDOM from "react-dom";
 
const container = document.getElementById("react");
ReactDOM.render(<App />, container);

Este é um ponto de entrada típico para um aplicativo React. Representa uma instância do importado. App componente como o elemento raiz do seu aplicativo. O conteúdo renderizado é depositado como innerHTML do elemento HTML com id="react".

Para mudar para a API raiz do React 18, substitua o código acima pelo seguinte:

import App from "./App.js";
import {createRoot} from "react-dom/client";
 
const container = document.getElementById("react");
const root = createRoot(container);
root.render(<App />);

Isso tem um efeito equivalente ao antigo ReactDOM.render() API. Em vez de inicializar um elemento raiz e renderizar seu aplicativo como uma única operação imperativa, o React 18 faz você primeiro criar um objeto raiz e depois renderizar explicitamente seu conteúdo.

Em seguida, localize qualquer lugar em seu código onde você desmonte seu nó raiz. Mudar ReactDOM.unmountComponentAtNode() para o novo unmount() método em seu objeto raiz:

// Before
import App from "./App.js";
import ReactDOM from "react-dom";
 
const container = document.getElementById("react");
ReactDOM.render(<App />, container);
ReactDOM.unmountComponentAtNode(container);
 
// After
import App from "./App.js";
import {createRoot} from "react-dom/client";
 
const container = document.getElementById("react");
const root = createRoot(container);
root.render(<App />);
root.unmount();

Substituição de callbacks de processamento

a ReactDOM.render() O argumento de retorno de chamada opcional do método não tem uma contrapartida direta na API raiz do React 18. Anteriormente, você podia usar esse código para fazer login Rendered! para o console após o React terminar de renderizar o nó raiz:

import App from "./App.js";
import ReactDOM from "react-dom";
 
const container = document.getElementById("react");
ReactDOM.render(<App />, container, () => console.log("Rendered!"));

Essa funcionalidade foi removida porque o tempo da chamada de retorno de chamada é imprevisível ao usar os novos recursos de hidratação parcial e renderização do servidor de streaming do React 18. Se você já estiver usando retornos de chamada de renderização e precisar manter a compatibilidade , poderá obter um comportamento semelhante usando o mecanismo refs:

import {createRoot} from "react-dom/client";
 
const App = ({callback}) => (
    <div ref={callback}>
        <h1>Demo App</h1>
    </div>
);
 
const container = document.getElementById("react");
const root = createRoot(container);
root.render(<App callback={() => console.log("Rendered!")} />);

React chama referências de função quando os componentes são montados. Definir uma referência ao componente que é seu nó raiz permite detectar quando a renderização ocorre, fornecendo um efeito semelhante ao antigo sistema de retorno de chamada de renderização.

Depurando problemas de atualização

Seu aplicativo agora deve ser renderizado usando os recursos do React 18 e sem nenhum aviso do console. Teste seu aplicativo completamente para garantir que tudo ainda esteja funcionando conforme o esperado. Se você encontrar problemas, poderá resolvê-los com essas resoluções comuns.

Procurar

Aplicativos envoltos em <StrictMode> O componente pode se comportar de maneira diferente quando renderizado no modo de desenvolvimento do React 18. Isso ocorre porque o modo estrito agora testa se sua base de código suporta o estado reutilizável, um conceito que será totalmente apresentado ao React em uma atualização posterior.

O estado reutilizável permite que o React remonte um componente excluído anteriormente com seu último estado restaurado automaticamente. Isso requer que seus componentes sejam resistentes a efeitos de invocação dupla. O modo estrito agora ajuda você a se preparar para o estado de rascunho, simulando a montagem, desmontagem e remontagem de seus componentes cada vez que eles são usados, revelando quaisquer problemas em que o estado anterior não possa ser restaurado. Você pode desabilitar o Strict Mode se encontrar problemas com seu aplicativo ou suas dependências que você não está pronto para resolver.

Suporta atualização de status de lote

O React 18 altera a forma como as atualizações de estado são “agregadas” para melhorar o desempenho. Quando você altera os valores de estado várias vezes em uma função, o React tenta combiná-los em uma única representação:

const Component = () => {
 
    const [query, setQuery] = useState("");
    const [queryCount, setQueryCount] = useState(0);
 
    /**
     * Two state updates, only one re-render
     */
    setQuery("demo");
    setQueryCount(queryCount + 1);
 
};

Esse mecanismo aumenta a eficiência, mas anteriormente só funcionava dentro de manipuladores de eventos React. Com o React 18, ele funciona com todas as atualizações de estado, mesmo se originadas de manipuladores de eventos nativos, timeouts ou promessas. Alguns códigos podem se comportar de maneira diferente de antes se você fizer atualizações de status consecutivas em qualquer um desses locais.

const Component = () => {
 
    const [query, setQuery] = useState("");
    const [queryId, setQueryId] = useState("");
    const [queryCount, setQueryCount] = useState(0);
 
    const handleSearch = query => {
       fetch(query).then(() => {
 
            setQuery("demo");
            setQueryCount(1);
 
            // In React 17, sets to "query-1"
            // In React 18, sets to "query-0" - previous state update is batched with this one
            setQueryId(`query-${queryCount}`);
 
        });
    }
 
};

Você pode desabilitar esse comportamento em situações em que não estiver pronto para refatorar seu código. Encapsular atualizações de status em flushSync() forçá-los a cometer imediatamente:

const Component = () => {
 
    const [query, setQuery] = useState("");
    const [queryId, setQueryId] = useState("");
    const [queryCount, setQueryCount] = useState(0);
 
    const handleSearch = query => {
       fetch(query).then(() => {
 
            flushSync(() => {
                setQuery("demo");
                setQueryCount(1);
            });
 
            // Sets to "query-1"
            setQueryId(`query-${queryCount}`);
 
        });
    }
 
};

Pare de usar recursos removidos e não suportados

Depois que todos os itens acima forem abordados, seu aplicativo deverá ser totalmente compatível com o React 18. Embora haja mais algumas alterações na superfície da API, elas não devem afetar a maioria dos aplicativos. Aqui estão alguns para manter em mente:

  • unstable_changedBits Ele foi removido – Esta API não suportada permitiu que você optasse por não receber atualizações de contexto. Não está mais disponível.
  • a Object.assign() O preenchimento poli foi removido. – Você deve adicionar manualmente o object-assign pacote polyfill se você precisar suportar navegadores muito antigos sem um Object.assign().
  • O Internet Explorer não é mais compatível – O React abandonou oficialmente o suporte ao Internet Explorer antes do fim do suporte ao navegador em junho. Você não deve atualizar para o React 18 se ainda precisar que seu aplicativo seja executado no IE.
  • Use o suspense com um undefined backup agora é equivalente a null – Limites de suspensão com fallback={undefined} eles foram ignorados anteriormente, permitindo que o código fosse em cascata para o próximo limite principal na árvore. O React 18 agora honra componentes de suspense não suportados.

Renderização do lado do servidor

Os aplicativos que usam renderização do lado do servidor exigirão mais algumas alterações para funcionar com o React 18.

De acordo com a nova API raiz, você precisa substituir a antiga hydrate() função em seu código do lado do cliente com o novo hydrateRoot() fornecida pelo react-dom/client pacote:

// Before
import App from "./App.js";
import ReactDOM from "react-dom";
 
const container = document.getElementById("react");
ReactDOM.hydrate(<App />, container);
 
// After
import App from "./App.js";
import {createRoot} from "react-dom/client";
 
const container = document.getElementById("react");
const root = hydrateRoot(container, <App />);

Em seu código do lado do servidor, substitua as chamadas de API de renderização obsoletas por suas novas contrapartes. Na maioria dos casos, você deve alterar renderToNodeStream() para o novo renderToReadableStream(). As novas APIs de streaming desbloqueiam o acesso aos recursos de renderização do servidor de streaming do React 18, onde o servidor pode continuar a fornecer novo HTML ao navegador após a renderização inicial do seu aplicativo.

Comece com os recursos do React 18

Agora que você atualizou, pode começar a tornar seu aplicativo mais poderoso incorporando recursos do React 18. O uso de simultaneidade do React significa que as renderizações de componentes podem ser interrompidas, desbloqueando novos recursos e uma interface do usuário mais responsiva.

Alguns dos recursos adicionados incluem atualizações importantes do Suspense, uma maneira de priorizar atualizações de status com Transitions e um mecanismo interno para acelerar re-renderizações causadas por atualizações não urgentes, mas de alta frequência. Existem também várias mudanças e melhorias diversas – você pode voltar undefined de um componente render() método, o aviso sobre a chamada setState() em componentes desmontados foi removido, e vários novos atributos HTML como imageSizes, imageSrcSetS aria-description eles são reconhecidos pelo renderizador React DOM.

Resumo

O React 18 é estável e pronto para uso. Na maioria dos casos, o processo de atualização deve ser rápido e fácil, exigindo apenas uma atualização do npm e uma mudança para a nova API raiz. No entanto, você ainda deve testar todos os seus componentes: eles podem se comportar de maneira diferente em algumas situações, como no modo estrito ou quando o lote automático é aplicado.

Esta nova versão aponta para a direção futura do React como um framework de alto desempenho para todos os tipos de aplicações web. Ele também estende os recursos de renderização do lado do servidor do React, adicionando Suspense do lado do servidor e a capacidade de continuar transmitindo conteúdo para seus usuários após a renderização inicial. Isso dá aos desenvolvedores mais flexibilidade para distribuir a renderização no cliente e no servidor.