Raziščite najboljše prakse za uporabo TypeScripta z Reactom za gradnjo robustnih, razširljivih in vzdrževanih spletnih aplikacij. Spoznajte strukturo projekta, oblikovanje komponent, testiranje in optimizacijo.
TypeScript z Reactom: Najboljše prakse za razširljive in vzdrževane aplikacije
TypeScript in React sta močna kombinacija za gradnjo sodobnih spletnih aplikacij. TypeScript prinaša statično tipiziranje v JavaScript, kar izboljšuje kakovost kode in vzdržljivost, medtem ko React ponuja deklarativen in na komponentah temelječ pristop k gradnji uporabniških vmesnikov. Ta objava na blogu raziskuje najboljše prakse za uporabo TypeScripta z Reactom za ustvarjanje robustnih, razširljivih in vzdrževanih aplikacij, primernih za globalno občinstvo.
Zakaj uporabljati TypeScript z Reactom?
Preden se poglobimo v najboljše prakse, poglejmo, zakaj je TypeScript dragocen dodatek k razvoju z Reactom:
- Izboljšana kakovost kode: Statično tipiziranje v TypeScriptu pomaga odkrivati napake zgodaj v razvojnem procesu, kar zmanjšuje težave med izvajanjem in izboljšuje zanesljivost kode.
- Povečana vzdržljivost: Opombe o tipih in vmesniki olajšajo razumevanje in preoblikovanje kode, kar vodi k boljši dolgoročni vzdržljivosti.
- Boljša podpora v IDE: TypeScript ponuja odlično podporo v integriranih razvojnih okoljih (IDE), vključno s samodejnim dokončanjem, navigacijo po kodi in orodji za preoblikovanje, kar povečuje produktivnost razvijalcev.
- Manj hroščev: Statično tipiziranje odkrije številne pogoste napake v JavaScriptu pred izvajanjem, kar vodi do bolj stabilne aplikacije brez hroščev.
- Izboljšano sodelovanje: Jasne definicije tipov olajšajo sodelovanje ekip na velikih projektih, saj lahko razvijalci hitro razumejo namen in uporabo različnih komponent in funkcij.
Vzpostavitev projekta TypeScript React
Uporaba Create React App
Najlažji način za začetek novega projekta TypeScript React je uporaba Create React App s predlogo TypeScript:
npx create-react-app my-typescript-react-app --template typescript
Ta ukaz nastavi osnovni projekt React z nastavljenim TypeScriptom, vključno s potrebnimi odvisnostmi in datoteko tsconfig.json
.
Konfiguracija datoteke tsconfig.json
Datoteka tsconfig.json
je srce vaše konfiguracije TypeScripta. Tukaj je nekaj priporočenih nastavitev:
{
"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 možnosti, ki jih je vredno upoštevati:
"strict": true
: Omogoči strogo preverjanje tipov, kar je zelo priporočljivo za odkrivanje morebitnih napak."esModuleInterop": true
: Omogoči interoperabilnost med moduli CommonJS in ES."jsx": "react-jsx"
: Omogoči novo JSX transformacijo, ki poenostavlja kodo Reacta in izboljšuje zmogljivost.
Najboljše prakse za komponente React s TypeScriptom
Tipiziranje lastnosti (props) komponente
Eden najpomembnejših vidikov uporabe TypeScripta z Reactom je pravilno tipiziranje lastnosti (props) vaše komponente. Uporabite vmesnike ali aliase tipov za definiranje oblike objekta props.
interface MyComponentProps {
name: string;
age?: number; // Izbirna lastnost
onClick: () => void;
}
const MyComponent: React.FC = ({ name, age, onClick }) => {
return (
Pozdravljen, {name}!
{age && Stari ste {age} let.
}
);
};
Uporaba React.FC<MyComponentProps>
zagotavlja, da je komponenta funkcionalna komponenta in da so lastnosti pravilno tipizirane.
Tipiziranje stanja (state) komponente
Če uporabljate razredne komponente, boste morali tipizirati tudi stanje komponente. Definirajte vmesnik ali alias tipa za objekt stanja in ga uporabite v 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 (
Število: {this.state.count}
);
}
}
Pri funkcionalnih komponentah, ki uporabljajo hook useState
, lahko TypeScript pogosto sklepa o tipu spremenljivke stanja, lahko pa ga tudi eksplicitno podate:
import React, { useState } from 'react';
const MyComponent: React.FC = () => {
const [count, setCount] = useState(0);
return (
Število: {count}
);
};
Uporaba varoval tipov (Type Guards)
Varovala tipov so funkcije, ki znotraj določenega obsega zožijo tip spremenljivke. Uporabna so pri delu z unijami tipov ali ko morate pred izvedbo operacije zagotoviti, da ima spremenljivka določen tip.
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 varovalo tipa, ki preverja, ali je Shape
(oblika) tipa Circle
(krog). Znotraj bloka if
TypeScript ve, da je shape
tipa Circle
, in vam omogoča dostop do njegove lastnosti radius
(polmer).
Obravnavanje dogodkov
Pri obravnavanju dogodkov v Reactu s TypeScriptom je pomembno pravilno tipizirati objekt dogodka. Uporabite ustrezen tip dogodka iz imenskega prostora React
.
const MyComponent: React.FC = () => {
const handleChange = (event: React.ChangeEvent) => {
console.log(event.target.value);
};
return (
);
};
V tem primeru se React.ChangeEvent<HTMLInputElement>
uporablja za tipiziranje objekta dogodka za dogodek spremembe na vnosnem elementu. To omogoča dostop do lastnosti target
, ki je HTMLInputElement
.
Struktura projekta
Dobro strukturiran projekt je ključnega pomena za vzdržljivost in razširljivost. Tukaj je predlagana struktura projekta za aplikacijo TypeScript React:
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:
- Komponente (components): Združite povezane komponente v mape. Vsaka mapa naj vsebuje TypeScript datoteko komponente, CSS module (če se uporabljajo) in datoteko
index.ts
za izvoz komponente. - Strani (pages): Shranite komponente najvišje ravni, ki predstavljajo različne strani vaše aplikacije.
- Storitve (services): V tej mapi implementirajte klice API-jev in druge storitve.
- Tipi (types): V tej mapi definirajte globalne definicije tipov in vmesnike.
- Pripomočki (utils): Shranite pomožne funkcije in konstante.
- index.ts: Uporabite datoteke
index.ts
za ponovni izvoz modulov iz mape, kar zagotavlja čist in organiziran API za uvoz modulov.
Uporaba hookov s TypeScriptom
React Hooki omogočajo uporabo stanja in drugih React funkcij v funkcionalnih komponentah. TypeScript deluje brezhibno s hooki, zagotavlja varnost tipov in izboljšano razvijalsko izkušnjo.
useState
Kot je bilo prikazano že prej, lahko pri uporabi useState
eksplicitno določite tip spremenljivke stanja:
import React, { useState } from 'react';
const MyComponent: React.FC = () => {
const [count, setCount] = useState(0);
return (
Število: {count}
);
};
useEffect
Pri uporabi useEffect
bodite pozorni na polje odvisnosti (dependency array). TypeScript vam lahko pomaga ujeti napake, če pozabite vključiti odvisnost, ki se uporablja znotraj učinka.
import React, { useState, useEffect } from 'react';
const MyComponent: React.FC = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Število: ${count}`;
}, [count]); // Dodajte 'count' v polje odvisnosti
return (
Število: {count}
);
};
Če izpustite count
iz polja odvisnosti, se bo učinek izvedel samo enkrat ob vpetju komponente, naslov dokumenta pa se ne bo posodobil ob spremembi števca. TypeScript vas bo opozoril na to potencialno težavo.
useContext
Pri uporabi useContext
morate določiti tip za vrednost konteksta.
import React, { createContext, useContext } from 'react';
interface ThemeContextType {
theme: string;
toggleTheme: () => void;
}
const ThemeContext = createContext(undefined);
const ThemeProvider: React.FC = ({ children }) => {
// Tu implementirajte logiko teme
return (
{} }}>
{children}
);
};
const MyComponent: React.FC = () => {
const { theme, toggleTheme } = useContext(ThemeContext) as ThemeContextType;
return (
Tema: {theme}
);
};
export { ThemeProvider, MyComponent };
Z določitvijo tipa za vrednost konteksta zagotovite, da hook useContext
vrne vrednost s pravilnim tipom.
Testiranje komponent TypeScript React
Testiranje je bistven del gradnje robustnih aplikacij. TypeScript izboljša testiranje z zagotavljanjem varnosti tipov in izboljšano pokritostjo kode.
Enotno testiranje (Unit Testing)
Uporabite ogrodja za testiranje, kot sta Jest in React Testing Library, za enotno testiranje vaših komponent.
// MyComponent.test.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('izriše komponento s pravilnim imenom', () => {
render( );
expect(screen.getByText('Pozdravljen, Janez!')).toBeInTheDocument();
});
it('pokliče obravnavo onClick, ko je gumb kliknjen', () => {
const onClick = jest.fn();
render( );
fireEvent.click(screen.getByRole('button'));
expect(onClick).toHaveBeenCalledTimes(1);
});
});
Preverjanje tipov v TypeScriptu pomaga odkrivati napake v vaših testih, na primer posredovanje napačnih lastnosti (props) ali uporabo napačnih obravnav dogodkov.
Integracijsko testiranje
Integracijski testi preverjajo, ali različni deli vaše aplikacije pravilno delujejo skupaj. Za testiranje od konca do konca (end-to-end) uporabite orodja, kot sta Cypress ali Playwright.
Optimizacija zmogljivosti
TypeScript lahko pomaga tudi pri optimizaciji zmogljivosti z odkrivanjem potencialnih ozkih grl v zmogljivosti zgodaj v razvojnem procesu.
Memoizacija
Uporabite React.memo
za memoizacijo funkcionalnih komponent in preprečevanje nepotrebnih ponovnih izrisovanj.
import React from 'react';
interface MyComponentProps {
name: string;
}
const MyComponent: React.FC = ({ name }) => {
console.log('Izrisovanje MyComponent');
return (
Pozdravljen, {name}!
);
};
export default React.memo(MyComponent);
React.memo
bo komponento ponovno izrisal le, če so se njene lastnosti (props) spremenile. To lahko znatno izboljša zmogljivost, zlasti pri zapletenih komponentah.
Razdeljevanje kode (Code Splitting)
Uporabite dinamične uvoze za razdelitev kode na manjše dele in njihovo nalaganje po potrebi. To lahko zmanjša začetni čas nalaganja vaše aplikacije.
import React, { Suspense } from 'react';
const MyComponent = React.lazy(() => import('./MyComponent'));
const App: React.FC = () => {
return (
Nalaganje...
React.lazy
vam omogoča dinamično uvažanje komponent, ki se naložijo šele, ko so potrebne. Komponenta Suspense
zagotavlja nadomestni uporabniški vmesnik, medtem ko se komponenta nalaga.
Zaključek
Uporaba TypeScripta z Reactom lahko znatno izboljša kakovost, vzdržljivost in razširljivost vaših spletnih aplikacij. Z upoštevanjem teh najboljših praks lahko izkoristite moč TypeScripta za gradnjo robustnih in zmogljivih aplikacij, ki ustrezajo potrebam globalnega občinstva. Ne pozabite se osredotočiti na jasne definicije tipov, dobro strukturirano organizacijo projekta in temeljito testiranje, da zagotovite dolgoročni uspeh svojih projektov.