TypeScript Academy · Oppitunti

Tila ja reducerit; Contextin tyypitys

Hallinnoikaa komponentin tilaa useState- ja useReducer-funktioilla, siirtäkää tila sitten tyypitettyyn Contextiin ja käyttäkää turvallista omaa hookia.

Oppitunti 2/38 vaihetta

Tila ja reducerit; Contextin tyypitys on ilmainen TypeScript Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/3. 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 TypeScript Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. TypeScript Academy-kurssilla on yhteensä 3 oppituntia.

Johdanto

Tavoite: Aloittakaa paikallisesta tilasta (useState), siirtykää tyypitettyyn reduceriin (useReducer) ja nostakaa tila lopuksi tyypitettyyn Contextiin, jossa on turvallinen mukautettu hook.

  • Mallintakaa tila ja toiminnot eksplisiittisesti
  • Suosikaa diskriminoituja unioneja
  • Suojatkaa Contextin käyttö

Tyypitetty useState

Tyypittäkää tila konkreettisella tyypillä (esimerkiksi number). Käyttäkää päivittäjämuotoa, jotta nopeat päivitykset eivät käytä vanhentuneita sulkeumia.

import React, { useState } from "react"

export default function Counter() {
  const [count, setCount] = useState<number>(0)

  const inc = () => setCount(c => c + 1)
  const dec = () => setCount(c => c - 1)

  return (
    <div style={{ display: "grid", gap: 8 }}>
      <div>Count: {count}</div>
      <div style={{ display: "flex", gap: 8 }}>
        <button onClick={inc}>+1</button>
        <button onClick={dec}>-1</button>
      </div>
    </div>
  )
}

Tyypitetty useReducer

Mallintakaa Action diskriminoituna unionina. switch pysyy kattavana, ja payloadit ovat tyypitettyjä haarakohtaisesti.

import React, { useReducer } from "react"

type State = { count: number }

type Action =
  | { type: "inc" }
  | { type: "add"; by: number }
  | { type: "reset" }

function reducer(s: State, a: Action): State {
  switch (a.type) {
    case "inc": return { count: s.count + 1 }
    case "add": return { count: s.count + a.by }
    case "reset": return { count: 0 }
  }
}

export default function App() {
  const [state, dispatch] = useReducer(reducer, { count: 0 })
  return (
    <div style={{ display: "grid", gap: 8 }}>
      <div>Count: {state.count}</div>
      <button onClick={() => dispatch({ type: "inc" })}>+1</button>
      <button onClick={() => dispatch({ type: "add", by: 5 })}>+5</button>
      <button onClick={() => dispatch({ type: "reset" })}>Reset</button>
    </div>
  )
}

Context + hook

Luokaa Context<T | null> ja tuokaa sitten käyttöön useX, joka heittää poikkeuksen null-arvon kohdalla. Käyttäjien koodi pysyy yksinkertaisena ja hyvin tyypitettynä.

import React, { createContext, useContext, useReducer } from "react"

type State = { count: number }

type Action = { type: "inc" } | { type: "add"; by: number } | { type: "reset" }

function reducer(s: State, a: Action): State {
  switch (a.type) {
    case "inc": return { count: s.count + 1 }
    case "add": return { count: s.count + a.by }
    case "reset": return { count: 0 }
  }
}

type Ctx = { state: State; dispatch: React.Dispatch<Action> }

const CounterCtx = createContext<Ctx | null>(null)

export function useCounter() {
  const ctx = useContext(CounterCtx)
  if (!ctx) throw new Error("useCounter must be used within CounterProvider")
  return ctx
}

export function CounterProvider({ children }: { children: React.ReactNode }) {
  const [state, dispatch] = useReducer(reducer, { count: 0 })
  return <CounterCtx.Provider value={{ state, dispatch }}>{children}</CounterCtx.Provider>
}

export default function App() {
  return (
    <CounterProvider>
      <Inner />
    </CounterProvider>
  )
}

function Inner() {
  const { state, dispatch } = useCounter()
  return (
    <div style={{ display: "grid", gap: 8 }}>
      <div>Count: {state.count}</div>
      <button onClick={() => dispatch({ type: "inc" })}>+1</button>
    </div>
  )
}

Context + reducer -kuvio

Jakakaa tilan lukeminen ja dispatchin lähettäminen komponenttien kesken. Provider ympäröi lapset ja tarjoaa tyypitetyn tilan sekä dispatchin.

import React from "react"
import { CounterProvider, useCounter } from "./ctx"

function Controls() {
  const { dispatch } = useCounter()
  return (
    <div style={{ display: "flex", gap: 8 }}>
      <button onClick={() => dispatch({ type: "inc" })}>+1</button>
      <button onClick={() => dispatch({ type: "add", by: 10 })}>+10</button>
      <button onClick={() => dispatch({ type: "reset" })}>Reset</button>
    </div>
  )
}

function View() {
  const { state } = useCounter()
  return <div>Count: {state.count}</div>
}

export default function App() {
  return (
    <CounterProvider>
      <div style={{ display: "grid", gap: 8 }}>
        <View />
        <Controls />
      </div>
    </CounterProvider>
  )
}

Parhaat käytännöt

Parhaat käytännöt:

  • Pitäkää tila mahdollisimman pienenä ja johtakaa loput arvot siitä.
  • Suosikaa diskriminoituja unioneja toiminnoissa.
  • Suojatkaa Contextin käyttö mukautetulla hookilla.

Contextin tyypityksen tarkistus

Pikatarkistus: Mikä on turvallinen tapa tyypittää React Context?

Kertaus

Kertaus: Aloittakaa useState-hookilla, mallintakaa tilasiirtymät useReducer-hookilla ja nostakaa jaettu tila mukautetun hookin suojaamaan tyypitettyyn Contextiin.

Aloita maksutta

Opi TypeScript 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
101
Oppitunnit
352

Usein kysytyt kysymykset

Onko oppitunti ”Tila ja reducerit; Contextin tyypitys” ilmainen?

Kyllä – oppitunnin ”Tila ja reducerit; Contextin tyypitys” 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 TypeScript Academy-kurssin, päivitä CoddyKit PROhon. TypeScript Academy-kurssilla on yhteensä 3 oppituntia.

Mitä opin oppitunnilla ”Tila ja reducerit; Contextin tyypitys”?

Hallinnoikaa komponentin tilaa useState- ja useReducer-funktioilla, siirtäkää tila sitten tyypitettyyn Contextiin ja käyttäkää turvallista omaa hookia. Harjoittelet TypeScript Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni TypeScript Academy-opiskelun?

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

Kuinka kauan ”Tila ja reducerit; Contextin tyypitys”-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ä TypeScript Academy-oppitunnilla?

Kyllä. Jokainen TypeScript 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. Propsit ja children; tapahtumankäsittelijät; ref-viittaukset
  2. Tila ja reducerit; Contextin tyypitys
  3. Komponenttien geneerisyys — johdanto
← Takaisin: TypeScript Academy