0Pricing
React Academy · บทเรียน

การกำหนดชนิด Context และ Custom Hooks

สร้าง Context ที่มีชนิดข้อมูลพร้อมค่าเริ่มต้น และเขียน Custom Hooks ที่ระบุชนิดค่าที่คืนกลับอย่างชัดเจน

การกำหนดชนิด Context และ Custom Hooks เป็นบทเรียน React Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

บริบทที่กำหนดชนิดด้วย createContext

ส่งชนิดบริบทและค่าเริ่มต้นให้กับ createContext ใช้ null เป็นค่าเริ่มต้นเมื่อจำเป็นต้องใช้บริบทภายในผู้ให้บริการ และจัดการกรณีนี้ด้วยตัวตรวจสอบ

interface AuthContextType {
  user: User | null;
  login: (credentials: Credentials) => Promise<void>;
  logout: () => void;
}

const AuthContext = createContext<AuthContextType | null>(null);

รูปแบบฮุกตัวตรวจสอบ

สร้างฮุกแบบกำหนดเองที่อ่านบริบทและโยนข้อผิดพลาดหากถูกใช้ภายนอกผู้ให้บริการ รูปแบบนี้ช่วยกำจัดการตรวจสอบค่า null ในทุกจุดที่เรียกใช้

export function useAuth(): AuthContextType {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error('useAuth must be used within AuthProvider');
  return ctx;
}

การกำหนดชนิดให้ผู้ให้บริการ

คอมโพเนนต์ผู้ให้บริการจะห่อองค์ประกอบลูกและจัดหาค่าบริบท ให้กำหนดชนิดของออบเจ็กต์ค่าอย่างชัดเจน เพื่อให้ TypeScript ตรวจสอบว่าตรงกับชนิดบริบท

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [user, setUser] = useState<User | null>(null);

  const login = async (creds: Credentials) => {
    const u = await apiLogin(creds);
    setUser(u);
  };

  const logout = () => setUser(null);

  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

บริบทที่มีค่าเริ่มต้น

เมื่อมีค่าเริ่มต้นที่เหมาะสม เช่น ธีม ให้ส่งค่านั้นโดยตรงให้กับ createContext เพื่อให้บริบทไม่เป็น null และไม่จำเป็นต้องใช้ฮุกตัวตรวจสอบ

interface ThemeContextType { theme: 'light' | 'dark'; toggle: () => void; }

const ThemeContext = createContext<ThemeContextType>({
  theme: 'light',
  toggle: () => {},
});

export const useTheme = () => useContext(ThemeContext);

การกำหนดชนิดค่าที่ฮุกแบบกำหนดเองส่งคืน

ระบุชนิดค่าที่ฮุกแบบกำหนดเองส่งคืนอย่างชัดเจน หรือปล่อยให้ TypeScript อนุมานชนิดนั้น ชนิดที่ระบุชัดเจนทำหน้าที่เป็นเอกสารประกอบและป้องกันการเปลี่ยนโครงสร้างโดยไม่ตั้งใจ

interface UseCounterReturn {
  count: number;
  increment: () => void;
  decrement: () => void;
  reset: () => void;
}

function useCounter(initial = 0): UseCounterReturn {
  const [count, setCount] = useState(initial);
  return {
    count,
    increment: () => setCount(c => c + 1),
    decrement: () => setCount(c => c - 1),
    reset: () => setCount(initial),
  };
}

ชนิดค่าที่ส่งคืนแบบทูเพิล

ฮุกที่ส่งคืนค่าเป็นคู่ เช่น useState จะใช้ทูเพิล ให้กำหนดชนิดด้วย as const หรือชนิดทูเพิลที่ระบุชัดเจน เพื่อให้การแยกโครงสร้างอนุมานชนิดได้อย่างถูกต้อง

function useToggle(initial = false): [boolean, () => void] {
  const [value, setValue] = useState(initial);
  const toggle = useCallback(() => setValue(v => !v), []);
  return [value, toggle];
}

// Destructuring correctly infers types:
const [isOpen, toggleOpen] = useToggle();

ฮุกแบบกำหนดเองที่เป็นเจเนริก

ฮุกแบบกำหนดเองสามารถเป็นเจเนริกได้เช่นกัน ฮุก useLocalStorage แบบเจเนริกจะจัดเก็บชนิดข้อมูลใด ๆ ที่แปลงเป็นอนุกรมได้ พร้อมความปลอดภัยด้านชนิดอย่างสมบูรณ์

function useLocalStorage<T>(key: string, initialValue: T): [T, (val: T) => void] {
  const [stored, setStored] = useState<T>(() => {
    try {
      const item = localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch { return initialValue; }
  });

  const setValue = (val: T) => {
    setStored(val);
    localStorage.setItem(key, JSON.stringify(val));
  };

  return [stored, setValue];
}

การกำหนดชนิดให้ useReducer

กำหนดชนิดแอ็กชันเป็นยูเนียนแบบจำแนกได้ และกำหนดโครงสร้างสถานะเป็นอินเทอร์เฟซ TypeScript จะบังคับให้ตัวลดใช้ชนิดแอ็กชันที่ถูกต้อง

interface State { count: number; status: 'idle' | 'loading'; }
type Action =
  | { type: 'INCREMENT' }
  | { type: 'SET_STATUS'; payload: State['status'] };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case 'INCREMENT': return { ...state, count: state.count + 1 };
    case 'SET_STATUS': return { ...state, status: action.payload };
  }
}

const [state, dispatch] = useReducer(reducer, { count: 0, status: 'idle' });

การกำหนดชนิดให้ useCallback และ useMemo

TypeScript อนุมานชนิดของ useCallback และ useMemo จากฟังก์ชันสร้างค่า ให้ระบุชนิดอย่างชัดเจนเฉพาะเมื่อการอนุมานล้มเหลว

const handleChange = useCallback(
  (e: React.ChangeEvent<HTMLInputElement>) => {
    onChange(e.target.value);
  },
  [onChange]
);

const sorted = useMemo(
  () => [...items].sort((a, b) => a.name.localeCompare(b.name)),
  [items]
); // inferred as typeof items

รูปแบบตัวเลือกบริบทพร้อมชนิด

ฮุกตัวเลือกที่กำหนดชนิดจะรับฟังก์ชันตัวเลือกและส่งคืนเฉพาะส่วนข้อมูลที่จำเป็น โดยยังคงการอนุมานชนิดอย่างสมบูรณ์

function useAuthSelector<T>(selector: (ctx: AuthContextType) => T): T {
  const ctx = useAuth();
  return selector(ctx);
}

// Usage — TypeScript infers User | null:
const user = useAuthSelector(ctx => ctx.user);

การหลีกเลี่ยง any ในฮุก

อย่าใช้ any ในฮุกแบบกำหนดเอง ให้ใช้เจเนริก ใช้ unknown ร่วมกับตัวตรวจสอบชนิด หรือใช้อินเทอร์เฟซเฉพาะ เพื่อรักษาสายการกำหนดชนิดให้สมบูรณ์

// Bad:
function useFetch(url: string): { data: any; loading: boolean } { ... }

// Good:
function useFetch<T>(url: string): { data: T | null; loading: boolean } {
  const [data, setData] = useState<T | null>(null);
  // ...
  return { data, loading };
}

ตรวจสอบอย่างรวดเร็ว

จุดประสงค์ของรูปแบบฮุกตัวตรวจสอบเมื่อกำหนดชนิดบริบท React คืออะไร

สรุปทบทวน

กำหนดชนิดบริบทด้วยอินเทอร์เฟซที่ชัดเจนและฮุกที่ตรวจสอบค่า null ระบุชนิดค่าที่ฮุกแบบกำหนดเองส่งคืนด้วยอินเทอร์เฟซหรือชนิดทูเพิล ใช้เจเนริกสำหรับฮุกที่นำกลับมาใช้ใหม่ได้ และกำหนดชนิดให้ useReducer ด้วยแอ็กชันแบบยูเนียนที่จำแนกได้ เพื่อจับการส่งแอ็กชันที่ไม่ถูกต้องตั้งแต่เวลาคอมไพล์

คำถามที่พบบ่อย

บทเรียน “การกำหนดชนิด Context และ Custom Hooks” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การกำหนดชนิด Context และ Custom Hooks” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การกำหนดชนิด Context และ Custom Hooks”

สร้าง Context ที่มีชนิดข้อมูลพร้อมค่าเริ่มต้น และเขียน Custom Hooks ที่ระบุชนิดค่าที่คืนกลับอย่างชัดเจน คุณปฏิบัติ React Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การกำหนดชนิด Context และ Custom Hooks” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน React Academy นี้ได้ไหม

ได้ บทเรียน React Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การกำหนดชนิด Props และชนิดค่าที่คอมโพเนนต์คืนกลับ
  2. การกำหนดชนิดอีเวนต์และ Refs ใน TypeScript
  3. คอมโพเนนต์แบบเจเนอริกและชนิดยูทิลิตี
  4. การกำหนดชนิด Context และ Custom Hooks
← กลับไปที่ React Academy