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:
- Forbedret kodekvalitet: TypeScript sin statiske typing hjelper med å fange feil tidlig i utviklingsprosessen, noe som reduserer kjøretidsfeil og forbedrer kodens pålitelighet.
- Økt vedlikeholdbarhet: Type-annotasjoner og grensesnitt gjør koden enklere å forstå og refaktorere, noe som fører til bedre langsiktig vedlikeholdbarhet.
- Bedre IDE-støtte: TypeScript gir utmerket IDE-støtte, inkludert autofullføring, kodenavigering og refaktoriseringsverktøy, noe som øker utviklerproduktiviteten.
- Reduserte feil: Statisk typing fanger mange vanlige JavaScript-feil før kjøretid, noe som fører til en mer stabil og feilfri applikasjon.
- Forbedret samarbeid: Tydelige typedefinisjoner gjør det enklere for team å samarbeide på store prosjekter, ettersom utviklere raskt kan forstå formålet med og bruken av forskjellige komponenter og funksjoner.
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:
"strict": true
: Aktiverer streng typesjekking, noe som er sterkt anbefalt for å fange potensielle feil."esModuleInterop": true
: Aktiverer interoperabilitet mellom CommonJS og ES-moduler."jsx": "react-jsx"
: Aktiverer den nye JSX-transformasjonen, som forenkler React-koden og forbedrer ytelsen.
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:
- Komponenter: Grupper relaterte komponenter i kataloger. Hver katalog bør inneholde komponentens TypeScript-fil, CSS-moduler (hvis brukt), og en
index.ts
-fil for å eksportere komponenten. - Sider: Lagre toppnivåkomponenter som representerer ulike sider i applikasjonen din.
- Tjenester: Implementer API-kall og andre tjenester i denne katalogen.
- Typer: Definer globale typedefinisjoner og grensesnitt i denne katalogen.
- Verktøy: Lagre hjelpefunksjoner og konstanter.
- index.ts: Bruk
index.ts
-filer for å re-eksportere moduler fra en katalog, noe som gir et rent og organisert API for import av moduler.
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.