Hrvatski

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:

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:

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:

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.

Dodatni resursi