Frontend Academy · Oppitunti

TypeScript Reactin kanssa: FC:n geneeriset tyypit ja hookit

Tyypitä React-komponentit geneeristen props-tyyppien avulla, määritä useState- ja useRef-kutsuille eksplisiittiset tyypit ja tyypitä tupleja palauttavat mukautetut hookit.

Oppitunti 3/413 vaihetta

TypeScript Reactin kanssa: FC:n geneeriset tyypit ja hookit on ilmainen Frontend Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Frontend Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Frontend Academy-kurssilla on yhteensä 4 oppituntia.

Komponenttien tyypitys

Modernissa Reactissa propit tyypitetään interfacella ja käytetään tavallista funktiota. React.FC on olemassa, mutta sitä ei enää suositella (children lisätään implisiittisesti, eikä geneerisiä tyyppejä tueta).

// Recommended:
interface ButtonProps {
  label: string;
  onClick: () => void;
  disabled?: boolean;
}

function Button({ label, onClick, disabled }: ButtonProps) {
  return <button onClick={onClick} disabled={disabled}>{label}</button>;
}

children-propin tyypitys

Käyttäkää React.ReactNode-tyyppiä mille tahansa renderöitävälle childille.

interface CardProps {
  title: string;
  children: React.ReactNode;
}

function Card({ title, children }: CardProps) {
  return (
    <div className="card">
      <h2>{title}</h2>
      {children}
    </div>
  );
}

useState-tyypitys

useState päättelee tyypin yleensä alkuarvosta. Antakaa eksplisiittinen tyyppi, kun alkuarvo on null tai ei edusta kaikkia mahdollisia tyyppejä.

const [count, setCount] = useState(0);              // number
const [name, setName] = useState('');                // string

const [user, setUser] = useState<User | null>(null); // explicit
const [items, setItems] = useState<Item[]>([]);      // explicit array type

useRef-tyypitys

Kaksi muotoa: DOM-elementtiin viittaava ref (alustetaan null-arvoksi) tai muuntuva säilö.

const inputRef = useRef<HTMLInputElement>(null);
const timerRef = useRef<number | null>(null);

useEffect(() => {
  inputRef.current?.focus();
  timerRef.current = window.setInterval(tick, 1000);
  return () => clearInterval(timerRef.current!);
}, []);

Tapahtumankäsittelijöiden tyypitys

Käyttäkää Reactin synteettisiä tapahtumatyyppejä.

function Form() {
  function onSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
  }
  function onChange(e: React.ChangeEvent<HTMLInputElement>) {
    setValue(e.target.value);
  }
  function onClick(e: React.MouseEvent<HTMLButtonElement>) {
    /* ... */
  }
  return <form onSubmit={onSubmit}>...</form>;
}

Geneeriset komponentit

Komponentit voivat olla geneerisiä — TypeScript päättelee tyyppiparametrin kutsukohdasta.

interface ListProps<T> {
  items: T[];
  renderItem: (item: T) => React.ReactNode;
  keyOf: (item: T) => string | number;
}

function List<T>({ items, renderItem, keyOf }: ListProps<T>) {
  return <ul>{items.map(i => <li key={keyOf(i)}>{renderItem(i)}</li>)}</ul>;
}

<List<User>
  items={users}
  renderItem={u => u.name}
  keyOf={u => u.id}
/>

Mukautettujen hookien tyypitys

Mukautetut hookit ovat funktioita — tyypittäkää ne kuten mikä tahansa muukin funktio. Palautettavat monikot tarvitsevat eksplisiittisen tyyppimerkinnän, jotta taulukon tyyppi ei levene.

function useToggle(initial = false): [boolean, () => void] {
  const [value, setValue] = useState(initial);
  const toggle = () => setValue(v => !v);
  return [value, toggle]; // tuple — annotation makes this stable
}

const [isOpen, toggle] = useToggle();

Contextin tyypitys

createContext tarvitsee alkuarvon, joka on samaa tyyppiä kuin annettava arvo. Käyttäkää non-null assertion -merkintää tai oletusobjektia.

interface AuthContextValue {
  user: User | null;
  signIn: (email: string, pw: string) => Promise<void>;
  signOut: () => void;
}

const AuthContext = createContext<AuthContextValue | null>(null);

export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error('useAuth must be inside AuthProvider');
  return ctx;
}

useReducer-tyypitys

Tyypittäkää tila ja action-unioni eksplisiittisesti.

type State = { count: number };
type Action =
  | { type: 'increment' }
  | { type: 'decrement' }
  | { type: 'set'; value: number };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case 'increment': return { count: state.count + 1 };
    case 'decrement': return { count: state.count - 1 };
    case 'set':       return { count: action.value };
  }
}

const [state, dispatch] = useReducer(reducer, { count: 0 });

React.FC:n välttäminen

React.FC on jäänyt pois suosiosta: se lisää children-propin implisiittisesti, ei tue geneerisiä komponentteja siististi ja estää joitakin optimointeja. Suosikaa tavallisia funktiokomponentteja, joiden propit on tyypitetty.

ComponentPropsWithoutRef-apuohjelmatyyppi

Jos haluatte periä natiivin elementin propsit (laajentaa button- tai input-elementtiä), käyttäkää ComponentPropsWithoutRef-tyyppiä.

type ButtonProps = React.ComponentPropsWithoutRef<'button'> & {
  variant?: 'primary' | 'secondary';
};

function Button({ variant = 'primary', ...rest }: ButtonProps) {
  return <button className={`btn ${variant}`} {...rest} />;
}

Pikatarkistus

Miksi React.FC-tyypin käyttöä yleensä vältetään ja sen sijaan suositaan tavallisia tyypitettyjä funktiokomponentteja?

Kertaus: TypeScript + React

Määritelkää propsien tyypit interface-määrittelyillä ja suosikaa tavallisia funktioita React.FC:n sijaan. children: React.ReactNode. useState päättelee tyypin usein automaattisesti, mutta tyypittäkää se erikseen null-arvoja tai tyhjiä taulukoita käytettäessä. Käyttäkää useRef-tyyppiä DOM-elementeille. Käyttäkää Reactin tapahtumatyyppejä käsittelijöissä. Käyttäkää geneerisiä komponentteja uudelleenkäytettäviin listoihin ja lomakkeisiin. Mukautetun hookin monikkopaluuarvo tarvitsee tyyppiannotaation. Laajentakaa natiiveja elementtejä ComponentPropsWithoutRef-tyypillä.

Aloita maksutta

Opi HTML tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
41
Oppitunnit
163

Usein kysytyt kysymykset

Onko oppitunti ”TypeScript Reactin kanssa: FC:n geneeriset tyypit ja hookit” ilmainen?

Kyllä – oppitunnin ”TypeScript Reactin kanssa: FC:n geneeriset tyypit ja hookit” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Frontend Academy-kurssin, päivitä CoddyKit PROhon. Frontend Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”TypeScript Reactin kanssa: FC:n geneeriset tyypit ja hookit”?

Tyypitä React-komponentit geneeristen props-tyyppien avulla, määritä useState- ja useRef-kutsuille eksplisiittiset tyypit ja tyypitä tupleja palauttavat mukautetut hookit. Harjoittelet Frontend Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Frontend Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Frontend Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”TypeScript Reactin kanssa: FC:n geneeriset tyypit ja hookit”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Frontend Academy-oppitunnilla?

Kyllä. Jokainen Frontend Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Template Literal -tyypit
  2. Dekoraattorit ja metadata
  3. TypeScript Reactin kanssa: FC:n geneeriset tyypit ja hookit
  4. Strict Mode ja any-tyypin poistaminen
← Takaisin: Frontend Academy