Norsk

Utforsk beste praksis for bruk av TypeScript med React for å bygge robuste, skalerbare og vedlikeholdbare webapplikasjoner. Lær om prosjektstruktur, komponentdesign, testing og optimalisering.

TypeScript med React: Beste praksis for skalerbare og vedlikeholdbare applikasjoner

TypeScript og React er en kraftig kombinasjon for å bygge moderne webapplikasjoner. TypeScript tilfører statisk typing til JavaScript, noe som forbedrer kodekvalitet og vedlikeholdbarhet, mens React tilbyr en deklarativ og komponentbasert tilnærming til å bygge brukergrensesnitt. Dette blogginnlegget utforsker beste praksis for bruk av TypeScript med React for å skape robuste, skalerbare og vedlikeholdbare applikasjoner som egner seg for et globalt publikum.

Hvorfor bruke TypeScript med React?

Før vi dykker ned i beste praksis, la oss forstå hvorfor TypeScript er et verdifullt tillegg til React-utvikling:

Sette opp et TypeScript React-prosjekt

Bruke Create React App

Den enkleste måten å starte et nytt TypeScript React-prosjekt på er å bruke Create React App med TypeScript-malen:

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

Denne kommandoen setter opp et grunnleggende React-prosjekt med TypeScript konfigurert, inkludert nødvendige avhengigheter og en tsconfig.json-fil.

Konfigurere tsconfig.json

Filen tsconfig.json er hjertet i din TypeScript-konfigurasjon. Her er noen anbefalte innstillinger:

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

Viktige alternativer å vurdere:

Beste praksis for React-komponenter med TypeScript

Type-setting av komponent-props

En av de viktigste aspektene ved å bruke TypeScript med React er å type-sette komponentenes props korrekt. Bruk grensesnitt eller type-aliaser for å definere formen på 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.

}
); };

Å bruke React.FC<MyComponentProps> sikrer at komponenten er en funksjonell komponent og at propsene er korrekt type-satt.

Type-setting av komponent-state

Hvis du bruker klassekomponenter, må du også type-sette komponentens state. Definer et grensesnitt eller en type-alias for state-objektet og bruk det i komponentdefinisjonen.

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 funksjonelle komponenter som bruker useState-hooken, kan TypeScript ofte utlede typen til state-variabelen, men du kan også eksplisitt angi den:

import React, { useState } from 'react';

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

  return (
    

Count: {count}

); };

Bruke Type Guards

Type guards er funksjoner som innsnevrer typen til en variabel innenfor et bestemt omfang. De er nyttige når man håndterer union-typer eller når du må sikre at en variabel har en spesifikk type før du utfører en operasjon.

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

Funksjonen isCircle er en type guard som sjekker om en Shape er en Circle. Innenfor if-blokken vet TypeScript at shape er en Circle og lar deg få tilgang til dens radius-egenskap.

Håndtering av hendelser

Når man håndterer hendelser i React med TypeScript, er det viktig å type-sette hendelsesobjektet korrekt. Bruk den passende hendelsestypen fra React-navnerommet.

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

  return (
    
  );
};

I dette eksempelet brukes React.ChangeEvent<HTMLInputElement> til å type-sette hendelsesobjektet for en endringshendelse på et input-element. Dette gir tilgang til target-egenskapen, som er en HTMLInputElement.

Prosjektstruktur

En velstrukturert prosjekt er avgjørende for vedlikeholdbarhet og skalerbarhet. Her er en foreslått prosjektstruktur for en TypeScript React-applikasjon:

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

Viktige punkter:

Bruke Hooks med TypeScript

React Hooks lar deg bruke state og andre React-funksjoner i funksjonelle komponenter. TypeScript fungerer sømløst med Hooks, og gir typesikkerhet og en forbedret utvikleropplevelse.

useState

Som vist tidligere, kan du eksplisitt type-sette state-variabelen når du bruker useState:

import React, { useState } from 'react';

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

  return (
    

Count: {count}

); };

useEffect

Når du bruker useEffect, vær oppmerksom på avhengighetslisten. TypeScript kan hjelpe deg med å fange feil hvis du glemmer å inkludere en avhengighet som brukes i effekten.

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

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

  useEffect(() => {
    document.title = `Count: ${count}`;
  }, [count]); // Legg til 'count' i avhengighetslisten

  return (
    

Count: {count}

); };

Hvis du utelater count fra avhengighetslisten, vil effekten kun kjøre én gang når komponenten monteres, og dokumenttittelen vil ikke oppdateres når telleren endres. TypeScript vil advare deg om dette potensielle problemet.

useContext

Når du bruker useContext, må du angi en type for kontekstverdien.

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

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

const ThemeContext = createContext(undefined);

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

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

  return (
    

Theme: {theme}

); }; export { ThemeProvider, MyComponent };

Ved å angi en type for kontekstverdien sikrer du at useContext-hooken returnerer en verdi med riktig type.

Testing av TypeScript React-komponenter

Testing er en essensiell del av å bygge robuste applikasjoner. TypeScript forbedrer testing ved å tilby typesikkerhet og forbedret kodedekning.

Enhetstesting

Bruk testrammeverk som Jest og React Testing Library for å enhetsteste komponentene dine.

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

TypeScript sin typesjekking hjelper til med å fange feil i testene dine, som for eksempel å sende inn feil props eller bruke feil hendelseshåndterere.

Integrasjonstesting

Integrasjonstester verifiserer at ulike deler av applikasjonen din fungerer korrekt sammen. Bruk verktøy som Cypress eller Playwright for ende-til-ende-testing.

Ytelsesoptimalisering

TypeScript kan også hjelpe med ytelsesoptimalisering ved å fange potensielle ytelsesflaskehalser tidlig i utviklingsprosessen.

Memoization

Bruk React.memo for å memoize funksjonelle komponenter og forhindre unødvendige re-rendringer.

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 re-rendre komponenten hvis propsene har endret seg. Dette kan forbedre ytelsen betydelig, spesielt for komplekse komponenter.

Kodeoppdeling

Bruk dynamiske importer for å dele opp koden din i mindre biter og laste dem ved behov. Dette kan redusere den innledende lastetiden til applikasjonen din.

import React, { Suspense } from 'react';

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

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

React.lazy lar deg dynamisk importere komponenter, som kun lastes når de trengs. Suspense-komponenten gir et reserve-UI mens komponenten lastes.

Konklusjon

Å bruke TypeScript med React kan betydelig forbedre kvaliteten, vedlikeholdbarheten og skalerbarheten til webapplikasjonene dine. Ved å følge disse beste praksisene kan du utnytte kraften i TypeScript til å bygge robuste og ytelsessterke applikasjoner som imøtekommer behovene til et globalt publikum. Husk å fokusere på tydelige typedefinisjoner, velstrukturert prosjektorganisering og grundig testing for å sikre den langsiktige suksessen til prosjektene dine.

Videre ressurser