Istražite najbolje prakse za korištenje TypeScripta s Reactom za izradu robusnih, skalabilnih i održivih web aplikacija. Saznajte više o strukturi projekta, dizajnu komponenti, testiranju i optimizaciji.
TypeScript s Reactom: Najbolje prakse za skalabilne i održive aplikacije
TypeScript i React moćna su kombinacija za izradu modernih web aplikacija. TypeScript donosi statičko tipiziranje u JavaScript, poboljšavajući kvalitetu i održivost koda, dok React pruža deklarativan pristup temeljen na komponentama za izgradnju korisničkih sučelja. Ovaj blog post istražuje najbolje prakse za korištenje TypeScripta s Reactom za stvaranje robusnih, skalabilnih i održivih aplikacija prikladnih za globalnu publiku.
Zašto koristiti TypeScript s Reactom?
Prije nego što se upustimo u najbolje prakse, shvatimo zašto je TypeScript vrijedan dodatak razvoju s Reactom:
- Poboljšana kvaliteta koda: Statičko tipiziranje TypeScripta pomaže u ranom otkrivanju grešaka tijekom razvojnog procesa, smanjujući probleme pri izvođenju i poboljšavajući pouzdanost koda.
- Poboljšana održivost: Anotacije tipova i sučelja čine kod lakšim za razumijevanje i refaktoriranje, što dovodi do bolje dugoročne održivosti.
- Bolja podrška u IDE okruženju: TypeScript pruža izvrsnu podršku u IDE okruženjima, uključujući automatsko dovršavanje, navigaciju kroz kod i alate za refaktoriranje, čime se povećava produktivnost programera.
- Smanjen broj bugova: Statičko tipiziranje hvata mnoge uobičajene JavaScript greške prije izvođenja, što dovodi do stabilnije aplikacije s manje bugova.
- Poboljšana suradnja: Jasne definicije tipova olakšavaju timovima suradnju na velikim projektima, jer programeri mogu brzo razumjeti svrhu i upotrebu različitih komponenti i funkcija.
Postavljanje TypeScript React projekta
Korištenje Create React App
Najlakši način za pokretanje novog TypeScript React projekta je korištenje Create React App s TypeScript predloškom:
npx create-react-app my-typescript-react-app --template typescript
Ova naredba postavlja osnovni React projekt s konfiguriranim TypeScriptom, uključujući potrebne ovisnosti i datoteku tsconfig.json
.
Konfiguriranje tsconfig.json
Datoteka tsconfig.json
srce je vaše TypeScript konfiguracije. Evo nekih preporučenih postavki:
{
"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"
]
}
Ključne opcije za razmatranje:
"strict": true
: Omogućuje strogu provjeru tipova, što se toplo preporučuje za hvatanje potencijalnih grešaka."esModuleInterop": true
: Omogućuje interoperabilnost između CommonJS i ES modula."jsx": "react-jsx"
: Omogućuje novu JSX transformaciju, koja pojednostavljuje React kod i poboljšava performanse.
Najbolje prakse za React komponente s TypeScriptom
Tipiziranje propova komponente
Jedan od najvažnijih aspekata korištenja TypeScripta s Reactom je pravilno tipiziranje propova vaše komponente. Koristite sučelja ili aliase tipova kako biste definirali oblik objekta s propovima.
interface MyComponentProps {
name: string;
age?: number; // Opcionalni prop
onClick: () => void;
}
const MyComponent: React.FC = ({ name, age, onClick }) => {
return (
Pozdrav, {name}!
{age && Imate {age} godina.
}
);
};
Korištenje React.FC<MyComponentProps>
osigurava da je komponenta funkcionalna i da su propovi ispravno tipizirani.
Tipiziranje stanja komponente
Ako koristite klasne komponente, također ćete trebati tipizirati stanje komponente. Definirajte sučelje ili alias tipa za objekt stanja i koristite ga u definiciji komponente.
interface MyComponentState {
count: number;
}
class MyComponent extends React.Component<{}, MyComponentState> {
state: MyComponentState = {
count: 0
};
handleClick = () => {
this.setState({
count: this.state.count + 1
});
};
render() {
return (
Brojač: {this.state.count}
);
}
}
Za funkcionalne komponente koje koriste useState
hook, TypeScript često može zaključiti tip varijable stanja, ali ga možete i eksplicitno navesti:
import React, { useState } from 'react';
const MyComponent: React.FC = () => {
const [count, setCount] = useState(0);
return (
Brojač: {count}
);
};
Korištenje čuvara tipova (Type Guards)
Čuvari tipova su funkcije koje sužavaju tip varijable unutar određenog opsega. Korisni su kada se radi s unijom tipova ili kada trebate osigurati da varijabla ima određeni tip prije izvođenja operacije.
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;
}
}
Funkcija isCircle
je čuvar tipa koji provjerava je li Shape
zapravo Circle
. Unutar if
bloka, TypeScript zna da je shape
tipa Circle
i omogućuje vam pristup njegovom svojstvu radius
.
Rukovanje događajima
Prilikom rukovanja događajima u Reactu s TypeScriptom, važno je ispravno tipizirati objekt događaja. Koristite odgovarajući tip događaja iz React
imenskog prostora.
const MyComponent: React.FC = () => {
const handleChange = (event: React.ChangeEvent) => {
console.log(event.target.value);
};
return (
);
};
U ovom primjeru, React.ChangeEvent<HTMLInputElement>
se koristi za tipiziranje objekta događaja za promjenu na input elementu. To omogućuje pristup svojstvu target
, koje je HTMLInputElement
.
Struktura projekta
Dobro strukturiran projekt ključan je za održivost i skalabilnost. Evo predložene strukture projekta za TypeScript React aplikaciju:
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
Ključne točke:
- Components: Grupirajte povezane komponente u direktorije. Svaki direktorij trebao bi sadržavati TypeScript datoteku komponente, CSS module (ako se koriste) i
index.ts
datoteku za izvoz komponente. - Pages: Pohranite komponente najviše razine koje predstavljaju različite stranice vaše aplikacije.
- Services: Implementirajte API pozive i druge servise u ovom direktoriju.
- Types: Definirajte globalne definicije tipova i sučelja u ovom direktoriju.
- Utils: Pohranite pomoćne funkcije i konstante.
- index.ts: Koristite
index.ts
datoteke za ponovni izvoz modula iz direktorija, pružajući čist i organiziran API za uvoz modula.
Korištenje hookova s TypeScriptom
React hookovi omogućuju korištenje stanja i drugih React značajki u funkcionalnim komponentama. TypeScript besprijekorno radi s hookovima, pružajući sigurnost tipova i poboljšano iskustvo za programere.
useState
Kao što je ranije prikazano, možete eksplicitno tipizirati varijablu stanja pri korištenju useState
:
import React, { useState } from 'react';
const MyComponent: React.FC = () => {
const [count, setCount] = useState(0);
return (
Brojač: {count}
);
};
useEffect
Kada koristite useEffect
, pazite na polje ovisnosti (dependency array). TypeScript vam može pomoći uhvatiti greške ako zaboravite uključiti ovisnost koja se koristi unutar efekta.
import React, { useState, useEffect } from 'react';
const MyComponent: React.FC = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Brojač: ${count}`;
}, [count]); // Dodajte 'count' u polje ovisnosti
return (
Brojač: {count}
);
};
Ako izostavite count
iz polja ovisnosti, efekt će se izvršiti samo jednom kada se komponenta montira, a naslov dokumenta se neće ažurirati kada se brojač promijeni. TypeScript će vas upozoriti na ovaj potencijalni problem.
useContext
Kada koristite useContext
, trebate navesti tip za vrijednost konteksta.
import React, { createContext, useContext } from 'react';
interface ThemeContextType {
theme: string;
toggleTheme: () => void;
}
const ThemeContext = createContext(undefined);
const ThemeProvider: React.FC = ({ children }) => {
// Implementirajte logiku teme ovdje
return (
{} }}>
{children}
);
};
const MyComponent: React.FC = () => {
const { theme, toggleTheme } = useContext(ThemeContext) as ThemeContextType;
return (
Tema: {theme}
);
};
export { ThemeProvider, MyComponent };
Navođenjem tipa za vrijednost konteksta, osiguravate da useContext
hook vraća vrijednost ispravnog tipa.
Testiranje TypeScript React komponenti
Testiranje je bitan dio izgradnje robusnih aplikacija. TypeScript poboljšava testiranje pružajući sigurnost tipova i bolju pokrivenost koda.
Jedinično testiranje (Unit Testing)
Koristite okvire za testiranje poput Jest i React Testing Library za jedinično testiranje vaših komponenti.
// MyComponent.test.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('renderira komponentu s točnim imenom', () => {
render( );
expect(screen.getByText('Pozdrav, Ivan!')).toBeInTheDocument();
});
it('poziva onClick handler kada se gumb klikne', () => {
const onClick = jest.fn();
render( );
fireEvent.click(screen.getByRole('button'));
expect(onClick).toHaveBeenCalledTimes(1);
});
});
TypeScript provjera tipova pomaže u hvatanju grešaka u vašim testovima, kao što je prosljeđivanje netočnih propova ili korištenje pogrešnih rukovatelja događajima.
Integracijsko testiranje
Integracijski testovi provjeravaju rade li različiti dijelovi vaše aplikacije ispravno zajedno. Koristite alate poput Cypressa ili Playwrighta za end-to-end testiranje.
Optimizacija performansi
TypeScript također može pomoći u optimizaciji performansi hvatanjem potencijalnih uskih grla u performansama rano u razvojnom procesu.
Memoizacija
Koristite React.memo
za memoizaciju funkcionalnih komponenti i sprječavanje nepotrebnih ponovnih renderiranja.
import React from 'react';
interface MyComponentProps {
name: string;
}
const MyComponent: React.FC = ({ name }) => {
console.log('Renderiranje MyComponent');
return (
Pozdrav, {name}!
);
};
export default React.memo(MyComponent);
React.memo
će ponovno renderirati komponentu samo ako su se propovi promijenili. To može značajno poboljšati performanse, posebno za složene komponente.
Razdvajanje koda (Code Splitting)
Koristite dinamički uvoz (dynamic imports) da biste podijelili svoj kod u manje dijelove i učitavali ih po potrebi. To može smanjiti početno vrijeme učitavanja vaše aplikacije.
import React, { Suspense } from 'react';
const MyComponent = React.lazy(() => import('./MyComponent'));
const App: React.FC = () => {
return (
Učitavanje...
React.lazy
vam omogućuje dinamičko uvoženje komponenti, koje se učitavaju samo kada su potrebne. Komponenta Suspense
pruža zamjensko korisničko sučelje dok se komponenta učitava.
Zaključak
Korištenje TypeScripta s Reactom može značajno poboljšati kvalitetu, održivost i skalabilnost vaših web aplikacija. Slijedeći ove najbolje prakse, možete iskoristiti snagu TypeScripta za izgradnju robusnih i performantnih aplikacija koje zadovoljavaju potrebe globalne publike. Ne zaboravite se usredotočiti na jasne definicije tipova, dobro strukturiranu organizaciju projekta i temeljito testiranje kako biste osigurali dugoročni uspjeh svojih projekata.