Als WordPress-Entwickler integrieren wir oft benutzerdefinierte React-Komponenten in unsere Themes und Plugins, um dynamische und reaktionsfähige Benutzeroberflächen zu schaffen.

Mit der bevorstehenden Veröffentlichung von React 19 ist es wichtig, sich auf Änderungen und Verwerfungen vorzubereiten, die sich auf unsere bestehenden Codebasen auswirken könnten. WordPress 6.6, das am 16. Juli veröffentlicht wird, enthält React 18.3. Diese Version ist fast identisch mit 18.2, enthält aber zusätzlich Warnungen für veraltete Funktionen, um dich auf React 19 vorzubereiten.

Die Berücksichtigung dieser veralteten Funktionen ist wichtig, um die Kompatibilität mit React 19 zu gewährleisten. Wenn du sie ignorierst, kann das zu Fehlern oder Problemen in deinen benutzerdefinierten Blöcken, Plugins oder Themes führen, wenn React 19 veröffentlicht und in WordPress integriert wird.

In diesem Artikel werden die einzelnen Verwerfungen beschrieben, mit Codebeispielen versehen und es wird erläutert, wie du veraltete Funktionen ersetzen kannst, um eine reibungslose Funktionalität zu gewährleisten.

Remote Verwerfungen in React

Mehrere veraltete APIs und Funktionen wurden entfernt, um die React-Bibliothek zu vereinfachen und Best Practices zu fördern. In diesem Abschnitt geht es um die wichtigsten Änderungen und wie du deinen Code entsprechend aktualisieren kannst.

1. Abschaffung von defaultProps für Funktionskomponenten

Mit React 19 wird defaultProps für Funktionskomponenten zugunsten von ES6-Standardparametern abgeschafft. Nach Angaben des WordPress-Teams wird diese Abschaffung am häufigsten in Plugins und Themes verwendet.

Als WordPress-Entwickler verwendest du vielleicht defaultProps, um Standardwerte für Props in deinen Funktionskomponenten bereitzustellen und sicherzustellen, dass sich die Komponenten auch dann korrekt verhalten, wenn bestimmte Props nicht übergeben werden.

Hier siehst du, wie dein aktueller Code mit defaultProps aussehen könnte:

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

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

In diesem Beispiel hat eine CustomButton Komponente die Standardwerte label und color, die von defaultProps bereitgestellt werden. In React 19 führt dies zu einer Fehlermeldung, die dich auffordert, stattdessen ES6-Standardparameter zu verwenden.

Hier ist der aktualisierte Code mit ES6-Standardparametern:

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

Bei der Verwendung von ES6-Standardparametern stehen die Standardwerte jetzt direkt in der Funktionssignatur, wodurch der Code leichter zu lesen und zu pflegen ist.

2. Die Entfernung von propTypes für Funktionskomponenten

propTypes wurde in React 15.5.0 veraltet und wird in v19 auch vollständig aus dem React-Paket entfernt. Wenn du propTypes verwendest, wird empfohlen, dass du zu TypeScript oder einer anderen Lösung für die Typüberprüfung migrierst.

Möglicherweise hast du propTypes verwendet, um die an deine Funktionskomponenten übergebenen Props zu validieren und sicherzustellen, dass sie die richtigen Typen und Werte erhalten. Zum Beispiel:

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,
};

Heute kannst du TypeScript für diese Typüberprüfungen verwenden:

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

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

3. Beseitigung von Legacy Context (contextTypes und getChildContext)

Da viele Plugins und Codebases in WordPress schon lange existieren, verwendest du in deinen Klassenkomponenten vielleicht noch die alten APIs contextTypes und getChildContext. Diese APIs wurden verwendet, um Daten von einer übergeordneten Komponente an ihre Nachkommen weiterzugeben, ohne dass auf jeder Ebene explizit Props übergeben wurden.

Es ist jedoch wichtig zu wissen, dass Legacy Context in React 16.6.0 veraltet ist und in React v19 abgeschafft wird. Diese Änderung soll React etwas kleiner und schneller machen, da die Legacy Context API subtile Bugs hatte, die oft leicht zu übersehen waren.

Die Legacy-Methode wurde durch die neue contextType API ersetzt.

Hier ist ein Beispiel dafür, wie du die veraltete Context-API in einem WordPress-Plugin verwenden kannst, um globale Einstellungen wie den Titel der Website von einer übergeordneten Komponente an eine untergeordnete Komponente zu übergeben, ohne Prop Drilling:

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>;
  }
}

Im Gegensatz dazu verwendet der moderne Ansatz die Methode createContext. Diese Methode solltest du übernehmen, wenn du dich auf React 19 vorbereitest:

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. Entfernung von String Refs

Die Verwendung von String Refs war früher eine gängige Methode, um auf ein DOM-Element in React-Komponenten zuzugreifen. Seit React 16.3.0 gelten sie jedoch als veraltet und werden in Version 19 entfernt.

String-Refs waren zwar einfach, hatten aber einige Probleme, wie z. B. mögliche Namenskonflikte und mangelnde Flexibilität.

Betrachte ein Beispiel für die Verwendung von String-Refs in einem benutzerdefinierten WordPress-Block. Stell dir vor, du hast einen benutzerdefinierten Gutenberg-Block, der ein Eingabefeld enthält, und du möchtest, dass das Eingabefeld automatisch fokussiert wird, wenn der Block dem Editor hinzugefügt wird. So hättest du das mit String-Refs machen können:

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

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

Um dich auf React 19 vorzubereiten, musst du String Refs durch Callbacks refs oder die React.createRef API ersetzen. Hier ist das gleiche Beispiel mit einem Callback ref:

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

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

5. Entfernung von Modul-Musterfabriken

Ein weiteres veraltetes Feature, das in React 19 entfernt wird, sind die Modul-Muster-Fabriken. Dieses Muster wurde nur selten verwendet und führte dazu, dass React etwas größer und langsamer war als nötig.

Modul-Musterfabriken ermöglichten es Entwicklern, Komponenten weniger konventionell zu erstellen. Hier ist ein Beispiel dafür, wie du es vielleicht verwendest:

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

Bei diesem Muster gibt SettingsPanelFactory ein Objekt mit einer render Methode zurück, anstatt JSX direkt zurückzugeben.

Um die Anforderungen von React 19 zu erfüllen, musst du die Modulmuster-Fabriken in reguläre Funktionen umwandeln, die JSX direkt zurückgeben. Hier ist das aktualisierte Beispiel:

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

6. Abschaffung der createFactory API

In React 19 wird React.createFactory entfernt. Diese Methode wurde häufiger verwendet, bevor JSX weithin unterstützt wurde. Sie ermöglichte es Entwicklern, React-Elemente zu erstellen, ohne die JSX-Syntax zu verwenden.

Mit der Verbreitung von JSX ist createFactory jedoch überflüssig geworden und kann durch einfacheren, besser lesbaren JSX-Code ersetzt werden.

Hier ist ein Beispiel für die Verwendung von createFactory zur Erstellung eines button Elements. Dies könnte Teil eines benutzerdefinierten WordPress-Plugins sein, das auf der Grundlage von Benutzereingaben dynamisch button Elemente erzeugt:

import { createFactory } from 'react';

const button = createFactory('button');

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

Um diesen Code für React 19 zu aktualisieren, ersetze createFactory durch JSX. Diese Änderung macht den Code moderner, lesbarer und wartbarer:

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

7. Entfernung von react-test-renderer/shallow

React 19 verabschiedet sich von react-test-renderer/shallow, um die Test-Utilities zu vereinfachen und Best Practices zu fördern. In React 18 wurde react-test-renderer/shallow aktualisiert und exportiert nun react-shallow-renderer.

Zuvor konntest du react-test-renderer/shallow verwenden, um flache Render-Tests für deine React-Komponenten zu erstellen:

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');
});

Um React 19 zu entsprechen, musst du die react-shallow-renderer:

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

Und aktualisiere deinen 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');
});

Das React-Team empfiehlt, auf die React Testing Library umzusteigen, die robustere Testverfahren bietet, indem sie sich darauf konzentriert, wie Nutzer mit deinen Komponenten interagieren.

Dazu installierst du die @testing-library/react Bibliothek als Dev-Abhängigkeit:

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

Als Nächstes kannst du die gleiche Komponente mit diesem modernen Ansatz testen:

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();
});

Entfernte Verwerfungen in React DOM

React DOM hat sich in React 19 ebenfalls verändert, indem bestimmte veraltete Methoden abgeschafft wurden. Dieser Abschnitt beschreibt diese Änderungen und führt dich durch die Aktualisierung deines DOM-bezogenen Codes.

1. Abschaffung der react-dom/test-utils API

Die react-dom/test-utils API wird in React 19 ebenfalls abgeschafft. Das wirkt sich darauf aus, wie wir Tests für unsere React-Komponenten schreiben. Konkret wurde das Dienstprogramm act von react-dom/test-utils in das Paket react verschoben.

Außerdem wurden die meisten anderen Hilfsprogramme aus react-dom/test-utils entfernt. Hier erfährst du, wie du deine Tests an diese Änderungen anpassen kannst.

Das Dienstprogramm act ist wichtig, um sicherzustellen, dass alle Aktualisierungen, die deine Tests betreffen, verarbeitet und auf das DOM angewendet wurden. In React 19 solltest du act direkt von react anstatt von react-dom/test-utils importieren.

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

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

Das React-Team empfiehlt außerdem, dass du deine Tests auf die React Testing Library umstellst, um ein modernes und gut unterstütztes Testerlebnis zu haben. Hier sind einige häufige Anwendungsfälle und wie du sie aktualisieren kannst.

Das Dienstprogramm renderIntoDocument wird entfernt. Du kannst es durch render von @testing-library/react ersetzen.

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

renderIntoDocument(<Component />);

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

render(<Component />);

Auch das Dienstprogramm Simulate zur Simulation von Ereignissen wurde entfernt. Stattdessen verwendest du nun fireEvent aus @testing-library/react, das ein tatsächliches Ereignis auf dem Element auslöst.

// 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);

Beachte, dass fireEvent ein echtes Ereignis auslöst, das heißt, es interagiert natürlicher mit dem Element als die synthetischen Ereignisse, die von Simulate erzeugt werden. Um die React-Testbibliothek richtig zu verstehen, lies die Dokumentation.

2. Abschaffung der findDOMNode API

Eine weitere wichtige Änderung in React 19 ist die Abschaffung von ReactDOM.findDOMNode, die in React 16.6.0 veraltet war.

Diese Funktion wurde verwendet, um auf den zugrundeliegenden DOM-Knoten einer React-Komponente zuzugreifen. Sie hatte jedoch mehrere Nachteile, z. B. war sie langsam in der Ausführung, anfällig für Refactoring und brach Abstraktionsebenen.

Stattdessen solltest du DOM refs verwenden, die eine zuverlässigere und effizientere Möglichkeit bieten, mit DOM-Elementen in deinen React-Komponenten zu interagieren.

Hier ist ein Beispiel für die Verwendung von findDOMNode, um den Text in einem Eingabefeld auszuwählen, wenn die Komponente hochgefahren wird:

import { findDOMNode } from 'react-dom';

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

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

Um diesen Code für React 19 zu aktualisieren, ersetze findDOMNode durch ref. Diese Änderung macht den Code robuster und passt ihn an moderne React-Praktiken an:

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

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

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

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

3. Entfernung der Render-API

Mit React 19 verabschieden wir uns von ReactDOM.render. Diese Methode wurde in React 18.0.0 zugunsten der createRoot API von react-dom/abgeschafft, die eine effizientere und modernere Methode zum Initialisieren und Rendern von React-Anwendungen bietet. Diese Änderung ist Teil der laufenden Bemühungen von React, die Bibliothek zu rationalisieren und zu optimieren.

In einem typischen WordPress-Setup hast du vielleicht einen benutzerdefinierten Block oder ein Plugin, das eine React-Anwendung initialisiert, wenn das DOM bereit ist. Bisher hast du ReactDOM.render verwendet:

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

Mit React 19 solltest du createRoot verwenden, um deine React-Anwendung zu initialisieren und zu rendern:

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

4. Entfernung der unmountComponentAtNode API

React 19 entfernt auch die Methode ReactDOM.unmountComponentAtNode, die in React 18.0.0 veraltet war. Diese Methode wurde verwendet, um eine React-Komponente aus dem DOM auszubauen.

In React 19 solltest du auf die Methode root.unmount() umsteigen, die besser mit der aktualisierten API für die Erstellung und Hydrierung von Roots übereinstimmt.

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

// Now
root.unmount();

5. Entfernung der Hydrate-API

ReactDOM.hydrate wurde in React 18 nicht weiter unterstützt und wird in React 19 vollständig entfernt werden.

Die neue Methode der React DOM-Client-API, hydrateRoot, ersetzt ReactDOM.hydrate und bietet eine effizientere und modernere Möglichkeit, servergerenderte React-Anwendungen zu hydrieren.

In einem WordPress-Kontext könntest du das serverseitige Rendering (SSR) verwenden, um den ursprünglichen HTML-Inhalt zu liefern, damit die Seite schneller geladen wird. Um diese Inhalte in eine interaktive React-Anwendung zu überführen, hast du bisher ReactDOM.hydrate verwendet:

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

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

Mit React 19 solltest du hydrateRoot von react-dom/client für die Hydrierung verwenden:

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

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

Abgeschaffte, veraltete TypeScript-Typen

WordPress-Entwickler verwenden häufig TypeScript, um Typsicherheit hinzuzufügen und die Codequalität in React-Komponenten zu verbessern. Mit React 19 wurden mehrere veraltete TypeScript-Typen entfernt oder in relevantere Pakete verlagert.

Das Verständnis dieser Änderungen ist wichtig, um sicherzustellen, dass deine Codebasis robust und kompatibel mit der neuesten React-Version bleibt.

Um die Umstellung zu erleichtern, hat das React-Team ein Tool namens types-react-codemod zur Verfügung gestellt, das deine Codebasis automatisch an diese Änderungen anpassen kann.

Um es zu nutzen, führe den folgenden codemod-Befehl aus, der mehrere Transformationen enthält, um veraltete Typen zu aktualisieren.

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

Das Tool bietet auch einen interaktiven Modus, in dem du bestimmte Transformationen auswählen kannst, die angewendet werden sollen:

? 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

Schauen wir uns einige wichtige Änderungen mit Beispielen an.

1. Ref Cleanup erforderlich

Mit React 19 verbessern die Cleanup-Funktionen von ref die Typsicherheit, indem sie explizite Rückgaben in ref Rückrufen erzwingen. Implizite Rückgaben können dazu führen, dass TypeScript den Rückgabewert falsch interpretiert.

// Before
 (instance = current)} />

// Now
 { instance = current }} />

2. useRef erfordert ein Argument

Zuvor konnte useRef ohne Argumente aufgerufen werden, was zu potenziellen Typproblemen führte. In React 19 benötigt useRef ein Argument, um sicherzustellen, dass Refs immer veränderbar sind.

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

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

3. Änderungen am ReactElement TypeScript-Typ

Der Standardtyp für ReactElement props wurde von any auf unknown geändert, was die Typsicherheit erhöht, da unbekannte Typen explizit behandelt werden müssen.

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

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

Wenn dein Code auf any basierte, musst du ihn aktualisieren, um unknown explizit zu behandeln oder ihn auf any zu casten.

Zusammenfassung

Als WordPress-Entwickler ist es wichtig, mit den neuesten Entwicklungen bei React Schritt zu halten. Dieser Leitfaden stellt sicher, dass du die verschiedenen Änderungen an React verstehst, damit du sie in deinen WordPress-Projekten anwenden kannst.

Eine letzte Information: Mit React 19 wird die neue JSX-Transformation erforderlich sein. Die gute Nachricht ist, dass sie bereits in WordPress 6.6 enthalten ist. Wenn die neue Transformation nicht aktiviert ist, wirst du diese Warnung sehen:

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

Alles, was du tun musst, ist, die React-Importe für JSX-Transformationen nicht mehr zu verwenden, da sie nicht mehr notwendig sind.

Haben wir etwas übersehen? Bitte teile es uns in den Kommentaren mit!

Joel Olawanle Kinsta

Joel is a Frontend developer working at Kinsta as a Technical Editor. He is a passionate teacher with love for open source and has written over 200 technical articles majorly around JavaScript and it's frameworks.