Stan i reducery; typowanie Context
Zarządzanie stanem komponentu za pomocą useState i useReducer, a następnie przeniesienie stanu do typowanego Context z bezpiecznym własnym hookiem
Stan i reducery; typowanie Context to bezpłatna lekcja TypeScript Academy na CoddyKit. To lekcja 2 z 3. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej TypeScript Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs TypeScript Academy zawiera 3 lekcji w sumie.
Wprowadzenie
Cel: Zacząć od stanu lokalnego (useState), przejść do typowanego reduktora (useReducer), a następnie podnieść stan do typowanego Contextu z bezpiecznym własnym hookiem.
- Jawne modelowanie stanu i akcji
- Preferowanie unii rozróżnianych
- Ochrona dostępu do Contextu
Typowany useState
Oznacz stan konkretnym typem (np. number). Używaj formy aktualizatora, aby uniknąć nieaktualnych domknięć podczas szybkich aktualizacji.
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>
)
}Typowany useReducer
Modeluj Action jako unię rozróżnianą. Instrukcja switch pozostaje kompletna, a payloady mają typy zależne od gałęzi.
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 i hook
Utwórz Context<T | null>, a następnie udostępnij useX, który zgłasza wyjątek, jeśli wartość jest null. Kod korzystający z Contextu pozostaje prosty i poprawnie typowany.
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>
)
}Wzorzec Contextu i reduktora
Rozdziel odczytywanie i wysyłanie akcji między komponenty. Provider opakowuje dzieci i dostarcza typowany stan oraz 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>
)
}Najlepsze praktyki
Najlepsze praktyki:
- Utrzymuj stan minimalny, a resztę wyliczaj.
- Preferuj unie rozróżniane dla akcji.
- Chroń dostęp do Contextu za pomocą własnego hooka.
Sprawdzanie typowania Contextu
Szybkie sprawdzenie: jaki jest bezpieczny sposób typowania React Contextu?
Podsumowanie
Podsumowanie: Zacznij od useState, modeluj przejścia za pomocą useReducer, a współdzielony stan przenieś do typowanego Contextu chronionego przez własny hook.
Często zadawane pytania
Czy lekcja „Stan i reducery; typowanie Context” jest bezpłatna?
Tak — pełny tekst „Stan i reducery; typowanie Context” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu TypeScript Academy, przejdź na CoddyKit PRO. Kurs TypeScript Academy zawiera 3 lekcji w sumie.
Co nauczysz się w „Stan i reducery; typowanie Context”?
Zarządzanie stanem komponentu za pomocą useState i useReducer, a następnie przeniesienie stanu do typowanego Context z bezpiecznym własnym hookiem Ćwiczysz TypeScript Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć TypeScript Academy?
Nie wymagamy żadnego doświadczenia. TypeScript Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 3.
Ile czasu zajmuje lekcja „Stan i reducery; typowanie Context”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji TypeScript Academy?
Tak. Każda lekcja TypeScript Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Props i children; obsługa zdarzeń; refs
- Stan i reducery; typowanie Context
- Generyki komponentów — wprowadzenie