State och reducers; Context-typning
Hantera komponentstate med useState och useReducer och lyft sedan state till en typad Context med en säker anpassad hook.
State och reducers; Context-typning är en gratis lektion i TypeScript Academy på CoddyKit. Detta är lektion 2 av 3. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för TypeScript Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i TypeScript Academy innehåller totalt 3 lektioner.
Introduktion
Mål: Börja med lokalt state (useState), gå vidare till en typad reducer (useReducer) och lyft sedan state till en typad Context med en säker anpassad hook.
- Modellera state och actions uttryckligen
- Föredra diskriminerade unioner
- Skydda åtkomst till Context
Typat useState
Ange state med en konkret typ (till exempel number). Använd uppdateringsformen för att undvika inaktuella closures vid snabba uppdateringar.
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>
)
}Typat useReducer
Modellera Action som en diskriminerad union. switch förblir uttömmande och payloads är typade per gren.
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 och hook
Skapa Context<T | null> och exponera sedan useX, som kastar ett fel om värdet är null. Användningen förblir enkel och vältypad.
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>
)
}Mönster med Context och reducer
Dela upp läsning och dispatching mellan komponenter. Provider omsluter children och tillhandahåller typat state och dispatch.
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>
)
}Bästa praxis
Bästa praxis:
- Håll state minimalt och härled resten.
- Föredra diskriminerade unioner för actions.
- Skydda åtkomsten till Context med en anpassad hook.
Kontroll av Context-typning
Snabb kontroll: Vad är ett säkert sätt att typa en React Context?
Sammanfattning
Sammanfattning: Börja med useState, modellera övergångar med useReducer och lyft delat state till en typad Context som skyddas av en anpassad hook.
Lär dig TypeScript med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 101
- Lektioner
- 352
Vanliga frågor
Är lektionen ”State och reducers; Context-typning” gratis?
Ja – hela texten till ”State och reducers; Context-typning” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i TypeScript Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i TypeScript Academy innehåller totalt 3 lektioner.
Vad lär jag mig i ”State och reducers; Context-typning”?
Hantera komponentstate med useState och useReducer och lyft sedan state till en typad Context med en säker anpassad hook. Ni övar på TypeScript Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig TypeScript Academy?
Du behöver inga förkunskaper. Utbildningen i TypeScript Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 3.
Hur lång tid tar lektionen ”State och reducers; Context-typning”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här TypeScript Academy-lektionen?
Ja. Varje TypeScript Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Props och children; händelsehanterare; refs
- State och reducers; Context-typning
- Komponentgenerics – introduktion