Dansk

Udforsk bedste praksis for at bruge TypeScript med React til at bygge robuste, skalerbare og vedligeholdelsesvenlige webapplikationer. Lær om projektstruktur, komponentdesign, test og optimering.

TypeScript med React: Bedste praksis for skalerbare og vedligeholdelsesvenlige applikationer

TypeScript og React er en stærk kombination til at bygge moderne webapplikationer. TypeScript bringer statisk typning til JavaScript, hvilket forbedrer kodekvaliteten og vedligeholdelsesvenligheden, mens React giver en deklarativ og komponentbaseret tilgang til at bygge brugergrænseflader. Dette blogindlæg udforsker bedste praksis for at bruge TypeScript med React til at skabe robuste, skalerbare og vedligeholdelsesvenlige applikationer, der er egnede til et globalt publikum.

Hvorfor bruge TypeScript med React?

Før vi dykker ned i den bedste praksis, lad os forstå, hvorfor TypeScript er en værdifuld tilføjelse til React-udvikling:

Opsætning af et TypeScript React-projekt

Brug af Create React App

Den nemmeste måde at starte et nyt TypeScript React-projekt er ved at bruge Create React App med TypeScript-skabelonen:

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

Denne kommando opsætter et grundlæggende React-projekt med TypeScript konfigureret, herunder nødvendige afhængigheder og en tsconfig.json-fil.

Konfiguration af tsconfig.json

tsconfig.json-filen er hjertet i din TypeScript-konfiguration. Her er nogle anbefalede indstillinger:

{
  "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"
  ]
}

Vigtige muligheder at overveje:

Bedste praksis for React-komponenter med TypeScript

Typning af komponent-props

Et af de vigtigste aspekter ved at bruge TypeScript med React er korrekt typning af dine komponent-props. Brug grænseflader eller typealiasser til at definere formen af props-objektet.

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

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

Hello, {name}!

{age &&

You are {age} years old.

}
); };

Brug af React.FC<MyComponentProps> sikrer, at komponenten er en funktionel komponent, og at propsene er korrekt typet.

Typning af komponenttilstand

Hvis du bruger klassekomponenter, skal du også type komponents tilstand. Definer en grænseflade eller typealias for tilstandsobjektet, og brug det i komponentdefinitionen.

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}

); } }

For funktionelle komponenter, der bruger useState-hooket, kan TypeScript ofte udlede typen af tilstandsvariablen, men du kan også eksplicit angive den:

import React, { useState } from 'react';

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

  return (
    

Count: {count}

); };

Brug af type guards

Type guards er funktioner, der indsnævrer typen af en variabel inden for et specifikt omfang. De er nyttige, når du har at gøre med unionstyper, eller når du skal sikre, at en variabel har en bestemt type, før du udfører en operation.

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

isCircle-funktionen er en type guard, der kontrollerer, om en Shape er en Circle. Inden for if-blokken ved TypeScript, at shape er en Circle og giver dig mulighed for at få adgang til dens radius-egenskab.

Håndtering af begivenheder

Når du håndterer begivenheder i React med TypeScript, er det vigtigt at type eventobjektet korrekt. Brug den relevante eventtype fra React-navneområdet.

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

  return (
    
  );
};

I dette eksempel bruges React.ChangeEvent<HTMLInputElement> til at type eventobjektet for en ændringsbegivenhed på et inputelement. Dette giver adgang til target-egenskaben, som er et HTMLInputElement.

Projektstruktur

En velstruktureret projekt er afgørende for vedligeholdelsesvenlighed og skalerbarhed. Her er en foreslået projektstruktur for en TypeScript React-applikation:

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

Vigtige punkter:

Brug af hooks med TypeScript

React Hooks giver dig mulighed for at bruge tilstand og andre React-funktioner i funktionelle komponenter. TypeScript fungerer problemfrit med Hooks, hvilket giver typesikkerhed og forbedret udvikleroplevelse.

useState

Som vist tidligere kan du eksplicit type tilstandsvariablen, når du bruger useState:

import React, { useState } from 'react';

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

  return (
    

Count: {count}

); };

useEffect

Når du bruger useEffect, skal du være opmærksom på afhængighedsarrayet. TypeScript kan hjælpe dig med at fange fejl, hvis du glemmer at inkludere en afhængighed, der bruges i effekten.

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

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

  useEffect(() => {
    document.title = `Count: ${count}`;
  }, [count]); // Tilføj 'count' til afhængighedsarrayet

  return (
    

Count: {count}

); };

Hvis du udelader count fra afhængighedsarrayet, køres effekten kun én gang, når komponenten monteres, og dokumentets titel opdateres ikke, når antallet ændres. TypeScript advarer dig om dette potentielle problem.

useContext

Når du bruger useContext, skal du angive en type for kontekstværdien.

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

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

const ThemeContext = createContext(undefined);

const ThemeProvider: React.FC = ({ children }) => {
  // Implementer temalogik her
  return (
     {} }}>
      {children}
    
  );
};

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

  return (
    

Theme: {theme}

); }; export { ThemeProvider, MyComponent };

Ved at angive en type for kontekstværdien sikrer du, at useContext-hooket returnerer en værdi med den korrekte type.

Test af TypeScript React-komponenter

Test er en væsentlig del af at bygge robuste applikationer. TypeScript forbedrer test ved at give typesikkerhed og forbedret kodedækning.

Enhedstest

Brug testrammer som Jest og React Testing Library til at enhedsteste dine komponenter.

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

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

TypeScript's typekontrol hjælper med at fange fejl i dine tests, såsom at sende forkerte props eller bruge de forkerte eventhandlere.

Integrationstest

Integrationstests verificerer, at forskellige dele af din applikation fungerer korrekt sammen. Brug værktøjer som Cypress eller Playwright til end-to-end-test.

Ydeevneoptimering

TypeScript kan også hjælpe med ydeevneoptimering ved at fange potentielle ydeevneflaskehalse tidligt i udviklingsprocessen.

Memoisering

Brug React.memo til at memoisere funktionelle komponenter og forhindre unødvendige gen-renderinger.

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 vil kun gen-rendere komponenten, hvis propsene er blevet ændret. Dette kan forbedre ydeevnen betydeligt, især for komplekse komponenter.

Kodesplitning

Brug dynamiske imports til at opdele din kode i mindre bidder og indlæse dem efter behov. Dette kan reducere den indledende indlæsningstid for din applikation.

import React, { Suspense } from 'react';

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

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

React.lazy giver dig mulighed for dynamisk at importere komponenter, som kun indlæses, når de er nødvendige. Suspense-komponenten giver en fallback-UI, mens komponenten indlæses.

Konklusion

Brug af TypeScript med React kan forbedre kvaliteten, vedligeholdelsesvenligheden og skalerbarheden af dine webapplikationer betydeligt. Ved at følge disse bedste praksis kan du udnytte kraften i TypeScript til at bygge robuste og performante applikationer, der opfylder behovene hos et globalt publikum. Husk at fokusere på klare typedefinitioner, velstruktureret projektorganisation og grundig test for at sikre den langsigtede succes for dine projekter.

Yderligere ressourcer