0Pricing
TypeScript Academy · درس

الحالة والمختزلات؛ كتابة Context

أدر حالة المكوّن باستخدام useState و useReducer، ثم ارفع الحالة إلى Context ذي أنواع باستخدام خطاف مخصص آمن.

الحالة والمختزلات؛ كتابة Context درس مجاني في TypeScript Academy على CoddyKit. هذا هو الدرس 2 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في TypeScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة TypeScript Academy 3 دروس في المجموع.

مقدمة

الهدف: ابدأ بالحالة المحلية (useState)، ثم انتقل إلى مخفّض ذي نوع محدد (useReducer)، ثم ارفع الحالة إلى Context ذي نوع محدد مع خطاف مخصّص آمن.

  • نمذجة الحالة والإجراءات بشكل صريح
  • تفضيل اتحادات الأنواع المميّزة
  • حماية الوصول إلى Context

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 ذو نوع محدد

نمذج Action على شكل اتحاد أنواع مميّز. يبقى 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 + الخطاف

أنشئ Context<T | null>، ثم وفّر useX يرمي خطأ إذا كانت القيمة 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>
  )
}

نمط Context + المخفّض

افصل بين القراءة والإرسال عبر المكوّنات. يغلّف Provider الأبناء ويزوّدهم بالحالة والإرسال ذوي النوع المحدد.

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

أفضل الممارسات

أفضل الممارسات:

  • حافظ على الحالة في أضيق نطاق ممكن، واشتقّ بقية القيم منها.
  • فضّل اتحادات الأنواع المميّزة للإجراءات.
  • احمِ الوصول إلى Context باستخدام خطاف مخصّص.

التحقق من نوع Context

تحقق سريع: ما الطريقة الآمنة لتحديد نوع React Context؟

مراجعة

مراجعة: ابدأ بـ useState، ونمذج الانتقالات باستخدام useReducer، وارفع الحالة المشتركة إلى Context ذي نوع محدد تحميه بخطاف مخصّص.

الأسئلة الشائعة

هل درس «الحالة والمختزلات؛ كتابة Context» مجاني؟

نعم — نص درس «الحالة والمختزلات؛ كتابة Context» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة TypeScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة TypeScript Academy 3 دروس في المجموع.

ماذا ستتعلم في «الحالة والمختزلات؛ كتابة Context»؟

أدر حالة المكوّن باستخدام useState و useReducer، ثم ارفع الحالة إلى Context ذي أنواع باستخدام خطاف مخصص آمن. تتمرن على TypeScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ TypeScript Academy؟

لا تُشترط خبرة سابقة. TypeScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 3.

كم من الوقت يستغرق درس «الحالة والمختزلات؛ كتابة Context»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس TypeScript Academy هذا؟

نعم. كل درس في TypeScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الخصائص والأبناء؛ معالجات الأحداث؛ المراجع
  2. الحالة والمختزلات؛ كتابة Context
  3. الأنواع العامة للمكوّنات — مقدمة
← العودة إلى TypeScript Academy