Deutsch

Erfahren Sie Best Practices für TypeScript mit React zur Entwicklung robuster, skalierbarer und wartbarer Webanwendungen. Behandelt Projektstruktur, Komponentendesign, Tests und Optimierung.

TypeScript mit React: Best Practices für skalierbare und wartbare Anwendungen

TypeScript und React sind eine leistungsstarke Kombination für die Entwicklung moderner Webanwendungen. TypeScript erweitert JavaScript um statische Typisierung, was die Codequalität und Wartbarkeit verbessert, während React einen deklarativen und komponentenbasierten Ansatz für die Erstellung von Benutzeroberflächen bietet. Dieser Blogbeitrag behandelt Best Practices für die Verwendung von TypeScript mit React, um robuste, skalierbare und wartbare Anwendungen zu erstellen, die für ein globales Publikum geeignet sind.

Warum TypeScript mit React verwenden?

Bevor wir uns den Best Practices widmen, wollen wir verstehen, warum TypeScript eine wertvolle Ergänzung zur React-Entwicklung ist:

Ein TypeScript React-Projekt einrichten

Verwendung von Create React App

Der einfachste Weg, ein neues TypeScript React-Projekt zu starten, ist die Verwendung von Create React App mit dem TypeScript-Template:

npx create-react-app my-typescript-react-app --template typescript

Dieser Befehl richtet ein grundlegendes React-Projekt mit konfigurierter TypeScript-Unterstützung ein, einschließlich der notwendigen Abhängigkeiten und einer tsconfig.json-Datei.

Konfiguration von tsconfig.json

Die Datei tsconfig.json ist das Herzstück Ihrer TypeScript-Konfiguration. Hier sind einige empfohlene Einstellungen:

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}

Wichtige Optionen, die zu beachten sind:

Best Practices für React-Komponenten mit TypeScript

Typisierung von Komponenten-Props

Einer der wichtigsten Aspekte bei der Verwendung von TypeScript mit React ist die korrekte Typisierung Ihrer Komponenten-Props. Verwenden Sie Interfaces oder Typaliase, um die Form des Props-Objekts zu definieren.

interface MyComponentProps {
  name: string;
  age?: number; // Optional prop
  onClick: () => void;
}

const MyComponent: React.FC = ({ name, age, onClick }) => {
  return (
    

Hello, {name}!

{age &&

You are {age} years old.

}
); };

Die Verwendung von React.FC<MyComponentProps> stellt sicher, dass die Komponente eine funktionale Komponente ist und dass die Props korrekt typisiert sind.

Typisierung des Komponentenstatus

Wenn Sie Klassenkomponenten verwenden, müssen Sie auch den Status der Komponente typisieren. Definieren Sie ein Interface oder einen Typalias für das Statusobjekt und verwenden Sie es in der Komponentendefinition.

interface MyComponentState {
  count: number;
}

class MyComponent extends React.Component<{}, MyComponentState> {
  state: MyComponentState = {
    count: 0
  };

  handleClick = () => {
    this.setState({
      count: this.state.count + 1
    });
  };

  render() {
    return (
      

Count: {this.state.count}

); } }

Für funktionale Komponenten, die den useState-Hook verwenden, kann TypeScript oft den Typ der Statusvariablen ableiten, Sie können ihn aber auch explizit angeben:

import React, { useState } from 'react';

const MyComponent: React.FC = () => {
  const [count, setCount] = useState(0);

  return (
    

Count: {count}

); };

Verwendung von Typ-Guards

Typ-Guards sind Funktionen, die den Typ einer Variablen innerhalb eines bestimmten Geltungsbereichs eingrenzen. Sie sind nützlich beim Umgang mit Union-Typen oder wenn Sie sicherstellen müssen, dass eine Variable einen bestimmten Typ hat, bevor Sie eine Operation ausführen.

interface Circle {
  kind: "circle";
  radius: number;
}

interface Square {
  kind: "square";
  side: number;
}

type Shape = Circle | Square;

function isCircle(shape: Shape): shape is Circle {
  return shape.kind === "circle";
}

function getArea(shape: Shape): number {
  if (isCircle(shape)) {
    return Math.PI * shape.radius ** 2;
  } else {
    return shape.side ** 2;
  }
}

Die Funktion isCircle ist ein Typ-Guard, der prüft, ob eine Shape ein Circle ist. Innerhalb des if-Blocks weiß TypeScript, dass shape ein Circle ist und erlaubt Ihnen, auf seine radius-Eigenschaft zuzugreifen.

Ereignisse behandeln

Beim Umgang mit Ereignissen in React mit TypeScript ist es wichtig, das Ereignisobjekt korrekt zu typisieren. Verwenden Sie den entsprechenden Ereignistyp aus dem React-Namensraum.

const MyComponent: React.FC = () => {
  const handleChange = (event: React.ChangeEvent) => {
    console.log(event.target.value);
  };

  return (
    
  );
};

In diesem Beispiel wird React.ChangeEvent<HTMLInputElement> verwendet, um das Ereignisobjekt für ein Änderungsereignis auf einem Eingabeelement zu typisieren. Dies ermöglicht den Zugriff auf die target-Eigenschaft, die ein HTMLInputElement ist.

Projektstruktur

Eine gut strukturierte Projektorganisation ist entscheidend für Wartbarkeit und Skalierbarkeit. Hier ist eine vorgeschlagene Projektstruktur für eine TypeScript React-Anwendung:

src/
├── components/
│   ├── MyComponent/
│   │   ├── MyComponent.tsx
│   │   ├── MyComponent.module.css
│   │   └── index.ts
├── pages/
│   ├── HomePage.tsx
│   └── AboutPage.tsx
├── services/
│   ├── api.ts
│   └── auth.ts
├── types/
│   ├── index.ts
│   └── models.ts
├── utils/
│   ├── helpers.ts
│   └── constants.ts
├── App.tsx
├── index.tsx
├── react-app-env.d.ts
└── tsconfig.json

Wichtige Punkte:

Verwendung von Hooks mit TypeScript

React Hooks ermöglichen es Ihnen, den Zustand und andere React-Funktionen in funktionalen Komponenten zu verwenden. TypeScript arbeitet nahtlos mit Hooks zusammen und bietet Typsicherheit sowie eine verbesserte Entwicklererfahrung.

useState

Wie bereits gezeigt, können Sie die Zustandsvariable explizit typisieren, wenn Sie useState verwenden:

import React, { useState } from 'react';

const MyComponent: React.FC = () => {
  const [count, setCount] = useState(0);

  return (
    

Count: {count}

); };

useEffect

Bei der Verwendung von useEffect sollten Sie auf das Abhängigkeits-Array achten. TypeScript kann Ihnen helfen, Fehler zu erkennen, wenn Sie vergessen, eine Abhängigkeit einzuschließen, die innerhalb des Effekts verwendet wird.

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

const MyComponent: React.FC = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `Count: ${count}`;
  }, [count]); // Add 'count' to the dependency array

  return (
    

Count: {count}

); };

Wenn Sie count aus dem Abhängigkeits-Array weglassen, wird der Effekt nur einmal ausgeführt, wenn die Komponente geladen wird, und der Dokumenttitel wird sich nicht aktualisieren, wenn sich der Zähler ändert. TypeScript wird Sie auf dieses potenzielle Problem hinweisen.

useContext

Bei der Verwendung von useContext müssen Sie einen Typ für den Kontextwert angeben.

import React, { createContext, useContext } from 'react';

interface ThemeContextType {
  theme: string;
  toggleTheme: () => void;
}

const ThemeContext = createContext(undefined);

const ThemeProvider: React.FC = ({ children }) => {
  // Implement theme logic here
  return (
     {} }}>
      {children}
    
  );
};

const MyComponent: React.FC = () => {
  const { theme, toggleTheme } = useContext(ThemeContext) as ThemeContextType;

  return (
    

Theme: {theme}

); }; export { ThemeProvider, MyComponent };

Indem Sie einen Typ für den Kontextwert angeben, stellen Sie sicher, dass der useContext-Hook einen Wert mit dem korrekten Typ zurückgibt.

Testen von TypeScript React-Komponenten

Tests sind ein wesentlicher Bestandteil beim Erstellen robuster Anwendungen. TypeScript verbessert Tests durch Typsicherheit und eine verbesserte Codeabdeckung.

Unit-Tests

Verwenden Sie Test-Frameworks wie Jest und React Testing Library, um Ihre Komponenten mit Unit-Tests zu überprüfen.

// MyComponent.test.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import MyComponent from './MyComponent';

describe('MyComponent', () => {
  it('renders the component with the correct name', () => {
    render();
    expect(screen.getByText('Hello, John!')).toBeInTheDocument();
  });

  it('calls the onClick handler when the button is clicked', () => {
    const onClick = jest.fn();
    render();
    fireEvent.click(screen.getByRole('button'));
    expect(onClick).toHaveBeenCalledTimes(1);
  });
});

Die Typprüfung von TypeScript hilft, Fehler in Ihren Tests abzufangen, wie z.B. das Übergeben falscher Props oder die Verwendung der falschen Ereignishandler.

Integrationstests

Integrationstests überprüfen, ob verschiedene Teile Ihrer Anwendung korrekt zusammenarbeiten. Verwenden Sie Tools wie Cypress oder Playwright für End-to-End-Tests.

Performance-Optimierung

TypeScript kann auch bei der Leistungsoptimierung helfen, indem es potenzielle Leistungsengpässe frühzeitig im Entwicklungsprozess erkennt.

Memoization

Verwenden Sie React.memo, um funktionale Komponenten zu memoizen und unnötige Neu-Renderings zu verhindern.

import React from 'react';

interface MyComponentProps {
  name: string;
}

const MyComponent: React.FC = ({ name }) => {
  console.log('Rendering MyComponent');
  return (
    

Hello, {name}!

); }; export default React.memo(MyComponent);

React.memo rendert die Komponente nur neu, wenn sich die Props geändert haben. Dies kann die Leistung erheblich verbessern, insbesondere bei komplexen Komponenten.

Code-Splitting

Verwenden Sie dynamische Importe, um Ihren Code in kleinere Chunks aufzuteilen und diese bei Bedarf zu laden. Dies kann die anfängliche Ladezeit Ihrer Anwendung reduzieren.

import React, { Suspense } from 'react';

const MyComponent = React.lazy(() => import('./MyComponent'));

const App: React.FC = () => {
  return (
    Laden...
}> ); };

React.lazy ermöglicht es Ihnen, Komponenten dynamisch zu importieren, die nur bei Bedarf geladen werden. Die Suspense-Komponente bietet eine Fallback-Benutzeroberfläche, während die Komponente lädt.

Fazit

Die Verwendung von TypeScript mit React kann die Qualität, Wartbarkeit und Skalierbarkeit Ihrer Webanwendungen erheblich verbessern. Durch Befolgung dieser Best Practices können Sie die Leistungsfähigkeit von TypeScript nutzen, um robuste und performante Anwendungen zu erstellen, die den Anforderungen eines globalen Publikums entsprechen. Denken Sie daran, sich auf klare Typdefinitionen, eine gut strukturierte Projektorganisation und gründliche Tests zu konzentrieren, um den langfristigen Erfolg Ihrer Projekte sicherzustellen.

Weitere Ressourcen