0Pricing
TypeScript Academy · 강의

상태와 리듀서, Context 타이핑

useState와 useReducer로 컴포넌트 상태를 관리한 다음, 안전한 사용자 지정 훅과 타입이 지정된 Context로 상태를 끌어올립니다.

상태와 리듀서, Context 타이핑은(는) CoddyKit의 무료 TypeScript Academy 강의입니다. 이것은 3개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 TypeScript Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. TypeScript Academy 강의에는 총 3개의 강의가 포함되어 있습니다.

소개

목표: 로컬 상태(useState)로 시작하여 타입이 지정된 리듀서(useReducer)로 전환한 다음, 안전한 사용자 지정 훅을 사용해 상태를 타입이 지정된 컨텍스트로 끌어올리십시오.

  • 상태와 액션을 명시적으로 모델링하기
  • 판별 유니언 우선 사용하기
  • 컨텍스트 접근 보호하기

useState 타입 지정

상태에 구체적인 타입(예: number)을 지정하십시오. 빠른 연속 업데이트에서 오래된 클로저를 피하려면 업데이트 함수 형식을 사용하십시오.

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 타입 지정

액션을 판별 유니언으로 모델링하십시오. switch는 모든 경우를 빠짐없이 처리하고, 각 분기에서 페이로드의 타입이 지정됩니다.

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<T | null>을 만든 다음, 값이 null이면 오류를 발생시키는 사용자 지정 훅을 제공하십시오. 사용하는 쪽의 코드는 간결하고 타입이 안전하게 유지됩니다.

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

컨텍스트와 리듀서 패턴

Component 간에 읽기와 디스패치를 분리하십시오. 공급자가 자식 요소를 감싸고 타입이 지정된 상태와 디스패치를 제공합니다.

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

모범 사례

모범 사례:

  • 상태는 최소화하고 나머지는 파생시키십시오.
  • 액션에는 판별 유니언을 우선 사용하십시오.
  • 사용자 지정 훅으로 컨텍스트 접근을 보호하십시오.

컨텍스트 타입 지정 확인

빠른 확인: React 컨텍스트에 타입을 지정하는 안전한 방법은 무엇입니까?

복습

복습: useState로 시작하고, useReducer로 상태 전환을 모델링하며, 사용자 지정 훅으로 보호되는 타입이 지정된 컨텍스트로 공유 상태를 끌어올리십시오.

자주 묻는 질문

“상태와 리듀서, Context 타이핑” 강의는 무료인가요?

네 — “상태와 리듀서, Context 타이핑” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 TypeScript Academy 강의 전체를 잠금 해제할 수 있습니다. TypeScript Academy 강의에는 총 3개의 강의가 포함되어 있습니다.

“상태와 리듀서, Context 타이핑”에서 뭘 배우나요?

useState와 useReducer로 컴포넌트 상태를 관리한 다음, 안전한 사용자 지정 훅과 타입이 지정된 Context로 상태를 끌어올립니다. 브라우저에서 직접 실행하는 실습 코드로 TypeScript Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

TypeScript Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 TypeScript Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 3개 중 2번째 강의입니다.

“상태와 리듀서, Context 타이핑” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 TypeScript Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 TypeScript Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. Props와 children, 이벤트 처리기와 refs
  2. 상태와 리듀서, Context 타이핑
  3. 컴포넌트 제네릭 — 입문
← TypeScript Academy(으)로 돌아가기