0Pricing
TypeScript Academy · Lezione

Stato e reducer; tipizzazione del Context

Gestisca lo stato dei componenti con useState e useReducer, quindi sollevi lo stato in un Context tipizzato con un custom hook sicuro.

Stato e reducer; tipizzazione del Context è una lezione TypeScript Academy gratuita su CoddyKit. Questa è la lezione 2 di 3. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento TypeScript Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso TypeScript Academy include 3 lezioni in totale.

Introduzione

Obiettivo: iniziare con lo stato locale (useState), passare a un reducer tipizzato (useReducer) e infine portare lo stato in un Context tipizzato con un custom hook sicuro.

  • Modellare esplicitamente lo stato e le azioni
  • Preferire le unioni discriminate
  • Proteggere l'accesso al Context

useState tipizzato

Annoti lo stato con un tipo concreto (ad es. number). Utilizzi la forma updater per evitare closure obsolete negli aggiornamenti rapidi.

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>
  )
}

useReducer tipizzato

Modelli Action come un'unione discriminata. Il switch resta esaustivo; i payload sono tipizzati in base al ramo.

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

Crei Context<T | null>, quindi esponga useX che solleva un'eccezione se il valore è null. I consumer restano semplici e ben tipizzati.

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>
  )
}

Pattern Context + reducer

Divida la lettura e il dispatch tra i componenti. Provider avvolge i children e fornisce stato + dispatch tipizzati.

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>
  )
}

Buone pratiche

Buone pratiche:

  • Mantenga lo stato minimale e ricavi tutto il resto.
  • Preferisca le unioni discriminate per le azioni.
  • Protegga l'accesso al Context con un custom hook.

Verifica della tipizzazione del Context

Verifica rapida: qual è un modo sicuro per tipizzare un Context React?

Riepilogo

Riepilogo: inizi con useState, modelli le transizioni con useReducer e porti lo stato condiviso in un Context tipizzato protetto da un custom hook.

Domande Frequenti

La lezione «Stato e reducer; tipizzazione del Context» è gratuita?

Sì — il testo completo di «Stato e reducer; tipizzazione del Context» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso TypeScript Academy, passa a CoddyKit PRO. Il corso TypeScript Academy include 3 lezioni in totale.

Cosa imparerò in «Stato e reducer; tipizzazione del Context»?

Gestisca lo stato dei componenti con useState e useReducer, quindi sollevi lo stato in un Context tipizzato con un custom hook sicuro. Eserciti TypeScript Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare TypeScript Academy?

Non è richiesta alcuna esperienza precedente. TypeScript Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 3.

Quanto tempo richiede la lezione «Stato e reducer; tipizzazione del Context»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione TypeScript Academy?

Sì. Ogni lezione TypeScript Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Props e children; gestori degli eventi; refs
  2. Stato e reducer; tipizzazione del Context
  3. Generics dei componenti — introduzione
← Torna a TypeScript Academy