Como desenvolvedores de WordPress, geralmente integramos componentes React personalizados em nossos temas e plugins para criar interfaces de usuário dinâmicas e responsivas.

Com o iminente lançamento do React 19, é fundamental preparar-se para mudanças e descontinuações que podem impactar nossas bases de código existentes. O WordPress 6.6, que será lançado em 16 de julho, inclui o React 18.3. Essa versão é quase idêntica ao 18.2, mas adiciona avisos sobre recursos descontinuados para ajudá-lo a se preparar para o React 19.

É essencial abordar essas descontinuações para garantir a compatibilidade com o React 19, e ignorá-las pode levar a bugs ou problemas em seus blocos, plugins ou temas personalizados quando o React 19 for lançado e incluído no WordPress.

Este artigo descreve cada descontinuação, fornece exemplos de código e orienta você na substituição de recursos descontinuados para manter a funcionalidade sem problemas.

Descontinuações removidas no React

Várias APIs e recursos descontinuados foram removidos para simplificar a biblioteca do React e incentivar as práticas recomendadas. Esta seção aborda as principais mudanças e como atualizar seu código de acordo com elas.

1. Remoção do defaultProps para componentes de função

O React 19 removerá o defaultProps para componentes de função em favor dos parâmetros padrão ES6. De acordo com a equipe WordPress, essa descontinuação é mais comumente usada em plugins e temas.

Como desenvolvedor WordPress, você poderia usar defaultProps para fornecer valores padrão para props em seus componentes de função, garantindo que os componentes se comportem corretamente mesmo que certos props não sejam passados.

O seu código atual com defaultProps pode se assemelhar a este:

function CustomButton({ label, color }) {
    return <button style={{ backgroundColor: color }}>{ label }</button>;
}

CustomButton.defaultProps = {
    label: 'Click me',
    color: 'blue',
};

Neste exemplo, um componente CustomButton tem valores padrão label e color fornecidos por defaultProps. Com o React 19, isso gerará um erro de aviso, solicitando que você use parâmetros padrão ES6.

Aqui está o código atualizado com os parâmetros padrão ES6:

function CustomButton({ label = 'Click me', color = 'blue' }) {
    return <button style={{ backgroundColor: color }}>{ label }</button>;
}

Usando os parâmetros padrão ES6, os valores padrão agora estão diretamente na assinatura da função, tornando o código mais fácil de ler e manter.

2. Remoção do propTypes para componentes de função

O recurso propTypes foi descontinuado no React 15.5.0 e agora será completamente removido do pacote do React na versão 19. Se você estiver usando propTypes, é recomendável migrar para TypeScript ou outra solução de verificação de tipos.

Você pode estar usando o propTypes para validar as propriedades passadas para os componentes da função para garantir que recebam os tipos e valores corretos. Por exemplo:

import PropTypes from 'prop-types';

function CustomButton({ label, color }) {
    return <button style={{ backgroundColor: color }}>{ label }</button>;
}

CustomButton.defaultProps = {
    label: 'Click me',
    color: 'blue',
};

CustomButton.propTypes = {
    label: PropTypes.string,
    color: PropTypes.string,
};

Hoje você pode começar a usar o TypeScript para essas verificações de tipo:

type CustomButtonProps = {
    label?: string;
    color?: string;
};

const CustomButton = ({ label = 'Click me', color = 'blue' }: CustomButtonProps) => {
    return <button style={{ backgroundColor: color }}>{ label }</button>;
};

3. Remoção do Legacy Context (contextTypes e getChildContext)

Dada a natureza de longa duração de muitos plugins e bases de código no WordPress, você ainda pode estar usando as APIs legadas contextTypes e getChildContext em seus componentes de classe. Essas APIs eram usadas para passar dados de um componente principal para seus descendentes sem passar explicitamente as propriedades em cada nível.

No entanto, é importante observar que o Legacy Context foi descontinuado no React 16.6.0 e será removido no React v19. Essa mudança visa tornar o React um pouco menor e mais rápido, pois a API Legacy Context tinha bugs sutis que facilmente passavam despercebidos.

O método legado foi substituído pela nova API contextType.

Aqui está um exemplo de como você pode estar usando a API Context descontinuada em um plugin WordPress para passar configurações globais, como o título do site, de um componente principal para um componente filho sem perfuração de props:

import PropTypes from 'prop-types';

class SettingsProvider extends React.Component {
  static childContextTypes = {
    siteTitle: PropTypes.string.isRequired,
  };

  getChildContext() {
    return { siteTitle: 'My WordPress Site' };
  }

  render() {
    return <SettingsConsumer />;
  }
}

class SettingsConsumer extends React.Component {
  static contextTypes = {
    siteTitle: PropTypes.string.isRequired,
  };

  render() {
    return <div>Site Title: {this.context.siteTitle}</div>;
  }
}

Em contraste, a abordagem moderna usa o método createContext. Esse é o método que você deve adotar ao se preparar para o React 19:

import React from 'react';

const SettingsContext = React.createContext();

class SettingsProvider extends React.Component {
  render() {
    return (
      <SettingsContext value={{ siteTitle: 'My WordPress Site' }}>
        <SettingsConsumer />
      </SettingsContext>
    );
  }
}

class SettingsConsumer extends React.Component {
  static contextType = SettingsContext;

  render() {
    const { siteTitle } = this.context;
    return <div>Site Title: { siteTitle }</div>;
  }
}

4. Remoção de refs de string

O uso de refs de string já foi uma maneira comum de acessar um elemento DOM em componentes React. No entanto, elas foram consideradas legadas desde o React 16.3.0 e serão removidas na versão 19.

Embora os refs de string fossem simples, tinham vários problemas, como possíveis conflitos de nomenclatura e falta de flexibilidade.

Considere um exemplo de uso de refs de string em um bloco personalizado do WordPress. Imagine que você tenha um bloco personalizado do Gutenberg que inclua um campo de entrada e queira que o campo de entrada seja focalizado automaticamente quando o bloco for adicionado ao editor. Veja como você poderia ter feito isso usando refs de string:

class CustomBlock extends React.Component {
  componentDidMount() {
    this.refs.input.focus();
  }

  render() {
    return <input ref="input" placeholder="Enter text..." />;
  }
}

Para se preparar para o React 19, você deve substituir os refs de string pelo callback refs ou pela API React.createRef. Aqui está o mesmo exemplo usando um callback ref:

class CustomBlock extends React.Component {
  componentDidMount() {
    this.input.focus();
  }

  render() {
    return <input ref={(input) => (this.input = input)} placeholder="Enter text..." />;
  }
}

5. Remoção das fábricas de padrão de módulo

Outro recurso descontinuado que será removido no React 19 são as fábricas de padrão de módulo. Esse padrão era raramente usado e fazia com que o React fosse ligeiramente maior e mais lento do que o necessário.

As fábricas de padrão de módulo permitiam que os desenvolvedores criassem componentes de maneira menos convencional. Aqui está um exemplo de como você pode estar usando isso:

function SettingsPanelFactory() {
  return {
    render() {
      return (
        <div className="settings-panel">
          <h2>Settings</h2>
          {/* other settings UI components */}
        </div>
      );
    }
  };
}

Nesse padrão, o SettingsPanelFactory retorna um objeto usando um método render em vez de retornar JSX diretamente.

Para estar em conformidade com o React 19, você deve migrar as fábricas de módulos para funções regulares que retornam JSX diretamente. Veja um exemplo atualizado:

function SettingsPanel() {
  return (
    <div className="settings-panel">
      <h2>Settings</h2>
      {/* other settings UI components */}
    </div>
  );
}

6. Remoção da API createFactory

No React 19, React.createFactory está sendo removido. Esse método era mais comumente usado antes de o JSX receber amplo suporte. Ele permitia que os desenvolvedores criassem elementos React sem usar a sintaxe JSX.

No entanto, com a prevalência do JSX, createFactory se tornou obsoleto e pode ser substituído por um código JSX mais simples e legível.

Aqui está um exemplo de uso do createFactory para criar um elemento button. Isso pode ser parte de um plugin WordPress personalizado que gera dinamicamente elementos button com base na entrada do usuário:

import { createFactory } from 'react';

const button = createFactory('button');

function CustomButton() {
  return button({ className: 'custom-button', type: 'button' }, 'Click Me');
}

Para atualizar esse código para o React 19, substitua createFactory por JSX. Essa alteração torna o código mais moderno, legível e de fácil manutenção:

function CustomButton() {
  return <button className="custom-button" type="button">Click Me</button>;
}

7. Remoção do react-test-renderer/shallow

O React 19 remove o react-test-renderer/shallow para simplificar os utilitários de teste e incentivar as práticas recomendadas. No React 18, react-test-renderer/shallow foi atualizado para reexportar react-shallow-renderer.

Anteriormente, você pode ter usado react-test-renderer/shallow para criar testes de renderização superficial para seus componentes React:

import ShallowRenderer from 'react-test-renderer/shallow';

test('MyComponent shallow render', () => {
  const renderer = new ShallowRenderer();
  renderer.render(<MyComponent />);
  const result = renderer.getRenderOutput();
  expect(result.type).toBe('div');
});

Para estar em conformidade com o React 19, você precisa instalar react-shallow-renderer:

npm install react-shallow-renderer --save-dev

E atualizar seu import:

import ShallowRenderer from 'react-shallow-renderer';

test('MyComponent shallow render', () => {
  const renderer = new ShallowRenderer();
  renderer.render(<MyComponent />);
  const result = renderer.getRenderOutput();
  expect(result.type).toBe('div');
});

A equipe do React recomenda a migração para a React Testing Library, que oferece práticas de teste mais robustas, concentrando-se em como os usuários interagem com os seus componentes.

Para fazer isso, instale a biblioteca @testing-library/react como uma dependência de desenvolvimento:

npm install @testing-library/react --save-dev

Em seguida, você pode testar o mesmo componente usando esta abordagem moderna:

import { render, screen } from '@testing-library/react';
import MyBlock from './MyBlock';

test('MyBlock renders correctly', () => {
  render(<MyBlock />);
  const element = screen.getByText('MyBlock content');
  expect(element).toBeInTheDocument();
});

Descontinuações removidas no React DOM

O React DOM também foi alterado no React 19, com a remoção de alguns métodos descontinuados. Esta seção descreve essas mudanças e orienta você na atualização do código relacionado ao DOM.

1. Remoção da API react-dom/test-utils

A API react-dom/test-utils também será removida no React 19. Isso afeta como escrevemos testes para nossos componentes React. Especificamente, o utilitário act foi movido de react-dom/test-utils para o pacote react.

Além disso, a maioria dos outros utilitários de react-dom/test-utils foi removida. Veja como você pode adaptar seus testes para se adequar a essas mudanças.

O utilitário act é essencial para garantir que todas as atualizações relacionadas aos seus testes tenham sido processadas e aplicadas ao DOM. No React 19, você deve importar act diretamente de react em vez de react-dom/test-utils.

// Before
import { act } from 'react-dom/test-utils';

// Now
import { act } from 'react';

A equipe do React também recomenda que você migre seus testes para a React Testing Library para ter uma experiência de teste moderna e com bom suporte. Aqui estão alguns casos de uso comuns e como atualizá-los.

O utilitário renderIntoDocument será removido. Você pode substituí-lo por render de @testing-library/react.

// Before
import { renderIntoDocument } from 'react-dom/test-utils';

renderIntoDocument(<Component />);

// Now
import { render } from '@testing-library/react';

render(<Component />);

Da mesma forma, o utilitário Simulate para simular eventos será removido. Em vez disso, você deve usar fireEvent de @testing-library/react, que envia um evento real para o elemento.

// Before
import { Simulate } from 'react-dom/test-utils';

const element = document.querySelector('button');
Simulate.click(element);

// Now
import { fireEvent } from '@testing-library/react';

const element = document.querySelector('button');
fireEvent.click(element);

Esteja ciente de que o fireEvent envia um evento real, o que significa que interage com o elemento de forma mais natural do que os eventos sintéticos criados pelo Simulate. Para entender corretamente a biblioteca de testes do React, leia sua documentação.

2. Remoção da API findDOMNode

Outra mudança significativa chegando ao React 19 é a remoção de ReactDOM.findDOMNode, que foi descontinuada no React 16.6.0.

Essa função era usada para acessar o node DOM subjacente de um componente React, mas tinha várias desvantagens, como lentidão na execução, fragilidade da refatoração e quebra dos níveis de abstração.

Em vez disso, você deve usar DOM refs, que fornecem uma maneira mais confiável e eficiente de interagir com elementos DOM em seus componentes React.

Aqui está um exemplo de uso do findDOMNode para selecionar o texto em um campo de entrada quando o componente é montado:

import { findDOMNode } from 'react-dom';

function AutoselectingInput() {
  useEffect(() => {
    const input = findDOMNode(this);
    input.select()
  }, []);

  render() {
    return <input defaultValue="Hello" />;
  }
}

Para atualizar esse código para o React 19, substitua findDOMNode por um ref. Essa alteração torna o código mais robusto e o alinha com as práticas modernas do React:

import React, { useEffect, useRef } from 'react';

function AutoselectingInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.select();
  }, []);

  return <input ref={inputRef} defaultValue="Hello" />;
}

3. Remoção da API de renderização

Com o React 19, ReactDOM.render será removido. Esse método foi descontinuado no React 18.0.0 em favor da API createRoot de react-dom/client, que fornece uma maneira mais eficiente e moderna de inicializar e renderizar aplicativos React. Essa alteração faz parte do esforço contínuo do React para simplificar e otimizar a biblioteca.

Em uma configuração típica de WordPress, você pode ter um bloco personalizado ou um plugin que inicializa um aplicativo React quando o DOM está pronto. Anteriormente, você usaria ReactDOM.render:

import { render } from 'react-dom';
render(<App />, document.getElementById('root'));

Com o React 19, você deve usar createRoot para inicializar e renderizar seu aplicativo React:

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

4. Remoção da API unmountComponentAtNode

O React 19 também remove o método ReactDOM.unmountComponentAtNode, que foi descontinuado no React 18.0.0. Esse método era usado para desmontar um componente React do DOM.

No React 19, você deve passar a utilizar o método root.unmount(), que está mais alinhado com a API atualizada para criar e hidratar raízes.

// Before
unmountComponentAtNode(document.getElementById('root'));

// Now
root.unmount();

5. Remoção da API hydrate

O ReactDOM.hydrate foi descontinuado no React 18 e será completamente removido no React 19.

O novo método da API do cliente React DOM, hydrateRoot, substitui o ReactDOM.hydrate, fornecendo uma maneira mais eficiente e moderna de hidratar aplicativos React renderizados no servidor.

Em um contexto de WordPress, você poderia usar a renderização do lado do servidor (SSR) para fornecer conteúdo HTML inicial para carregamentos de página mais rápidos. Para hidratar esse conteúdo em um aplicativo React interativo, anteriormente você usaria o ReactDOM.hydrate:

import { hydrate } from 'react-dom';
import App from './App.js';

hydrate(
  <App />,
  document.getElementById('root')
);

Com o React 19, você deve usar hydrateRoot de react-dom/client para hidratação:

import { hydrateRoot } from 'react-dom/client';
import App from './App.js';

hydrateRoot(
  document.getElementById('root'),
  <App />
);

Remoção de tipos TypeScript descontinuados

Os desenvolvedores WordPress costumam usar o TypeScript para adicionar segurança de tipos e melhorar a qualidade do código nos componentes do React. Com o React 19, vários tipos de TypeScript descontinuados foram removidos ou realocados para pacotes mais relevantes.

Entender essas alterações é crucial para garantir que sua base de código permaneça robusta e compatível com a versão mais recente do React.

Para ajudar na transição, a equipe do React forneceu uma ferramenta chamada types-react-codemod, que pode atualizar automaticamente sua base de código para lidar com essas alterações.

Para usá-la, execute o seguinte comando codemod, que inclui várias transformações para atualizar tipos descontinuados.

npx types-react-codemod@latest preset-19 ./path-to-app

A ferramenta também oferece um modo interativo no qual você pode escolher transformações específicas para aplicar:

? Pick transforms to apply (Press  to select,  to toggle all,  to invert selection, and  to proceed)
❯◯ context-any
◉ deprecated-react-type
◉ deprecated-sfc-element
◉ deprecated-sfc
◉ deprecated-stateless-component
◯ implicit-children
◯ useCallback-implicit-any

Vamos dar uma olhada em algumas das principais alterações com exemplos.

1. Exigência de limpeza de refs

Com o React 19, as funções de limpeza de ref melhoram a segurança de tipos ao exigir retornos explícitos em callbacks de ref. Retornos implícitos podem fazer com que o TypeScript interprete incorretamente o valor de retorno.

// Before
 (instance = current)} />

// Now
 { instance = current }} />

2. O useRef exige um argumento

Anteriormente, useRef podia ser chamado sem argumentos, o que levava a possíveis problemas de tipagem. No React 19, useRef requer um argumento para garantir que os refs sejam sempre mutáveis.

// Before — @ts-expect-error: Expected 1 argument but saw none
useRef();

// Now — correct usage with an argument
useRef(undefined);

3. Alterações no Tipo TypeScript de ReactElement

O tipo padrão para props de ReactElement foi alterado de any para unknown, melhorando a segurança de tipos ao exigir o tratamento explícito de tipos desconhecidos.

// Previously, this was 'any'
type Example = ReactElement["props"];

// Now, this is 'unknown'
type Example = ReactElement["props"];

Se o seu código dependia do any, você deve atualizá-lo para lidar explicitamente com unknown ou convertê-lo para any.

Resumo

É fundamental que desenvolvedores WordPress se mantenham sempre atualizados com os avanços do React. Este guia garante que você entenda as várias mudanças que estão chegando ao React para que possa aplicá-las aos seus projetos WordPress.

Uma última informação: com o React 19, a nova transformação JSX será obrigatória. A boa notícia é que ela já vem com o WordPress 6.6. Se a nova transformação não estiver habilitada, você verá este aviso:

Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance: https://react.dev/link/new-jsx-transform

Tudo o que é preciso é parar de usar imports do React para transformações JSX, pois não são mais necessários.

Deixamos passar algo? Compartilhe conosco na seção de comentários!

Joel Olawanle Kinsta

Joel é um desenvolvedor Frontend que trabalha na Kinsta como Editor Técnico. Ele é um professor apaixonado com amor pelo código aberto e já escreveu mais de 200 artigos técnicos, principalmente sobre JavaScript e seus frameworks.