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.
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.
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
- Propsit ja children; tapahtumankäsittelijät; ref-viittaukset
- Tila ja reducerit; Contextin tyypitys
- Komponenttien geneerisyys — johdanto