TypeScript / React Hooks төрөлжүүлэх

React Hooks төрөлжүүлэх

React Hooks — useState, useEffect, useRef, useCallback — TypeScript-тэй хамт маш хүчирхэг болдог. TypeScript state-ийн төрлийг автоматаар таниж, буруу утга оноохоос сэргийлнэ.

Энэ хичээлд хамгийн өргөн хэрэглэгддэг hook-уудыг TypeScript-ааар зөв бичих аргыг сурна.

useState төрөлжүүлэх

useState ихэнх тохиолдолд TypeScript эхний утгаасаа төрлийг автоматаар таних тул тусдаа зааж өгөх шаардлагагүй:

tsx
"use client";

import { useState } from "react";

function Тоолуур() {
  // TypeScript: тоо гэж автоматаар таних
  const [тоо, setТоо] = useState(0);

  // TypeScript: мөр гэж автоматаар таних
  const [нэр, setНэр] = useState("Болд");

  // TypeScript: boolean гэж автоматаар таних
  const [нээлттэй, setНээлттэй] = useState(false);

  return (
    <div>
      <p>Тоо: {тоо}</p>
      <button onClick={() => setТоо(тоо + 1)}>Нэмэх</button>
      <button onClick={() => setТоо("текст")}>
        {/* Алдаа! string биш number хэрэгтэй */}
      </button>
    </div>
  );
}

Анхны утга null эсвэл undefined байх тохиолдолд Generic хэрэглэж төрлийг тодорхой заах хэрэгтэй:

tsx
interface Хэрэглэгч {
  id: string;
  нэр: string;
  и_мэйл: string;
}

function ПрофайлХуудас() {
  // null байж болох тул Generic заана
  const [хэрэглэгч, setХэрэглэгч] = useState<Хэрэглэгч | null>(null);
  const [алдаа, setАлдаа] = useState<string | null>(null);
  const [ачааллаж, setАчааллаж] = useState<boolean>(false);

  if (ачааллаж) return <p>Ачааллаж байна...</p>;
  if (алдаа) return <p>Алдаа: {алдаа}</p>;
  if (!хэрэглэгч) return <p>Нэвтрээгүй байна</p>;

  return <p>Сайн уу, {хэрэглэгч.нэр}!</p>;
}

useEffect төрөлжүүлэх

useEffect өөрөө тусгай Generic шаарддаггүй — гэхдээ дотор хэрэглэх утгуудыг зөв төрөлжүүлэх нь чухал:

tsx
"use client";

import { useState, useEffect } from "react";

interface Нийтлэл {
  id: number;
  title: string;
  body: string;
}

function НийтлэлijinДэлгэрэнгүй({ id }: { id: number }) {
  const [нийтлэл, setНийтлэл] = useState<Нийтлэл | null>(null);
  const [ачааллаж, setАчааллаж] = useState(true);

  useEffect(() => {
    // Async функцийг useEffect дотор дуудах зөв арга
    async function өгөгдөлАвах() {
      try {
        const res = await fetch(
          `https://jsonplaceholder.typicode.com/posts/${id}`,
        );
        const data: Нийтлэл = await res.json();
        setНийтлэл(data);
      } catch {
        console.error("Өгөгдөл авахад алдаа гарлаа");
      } finally {
        setАчааллаж(false);
      }
    }

    өгөгдөлАвах();
  }, [id]); // id өөрчлөгдөхөд дахин ажиллана

  if (ачааллаж) return <p>Ачааллаж байна...</p>;
  if (!нийтлэл) return <p>Нийтлэл олдсонгүй</p>;

  return (
    <article>
      <h1>{нийтлэл.title}</h1>
      <p>{нийтлэл.body}</p>
    </article>
  );
}

useRef төрөлжүүлэх

useRef DOM элемент дээр хэрэглэхэд Generic-д тухайн HTML элементийн төрлийг заана:

tsx
"use client";

import { useRef } from "react";

function ХайлтынМаягт() {
  // HTMLInputElement — input элементийн TypeScript төрөл
  const оролтынRef = useRef<HTMLInputElement>(null);

  const фокусТавих = () => {
    // null шалгасны дараа л ашиглана
    if (оролтынRef.current) {
      оролтынRef.current.focus();
      оролтынRef.current.select(); // бүх текст сонгох
    }
  };

  return (
    <div>
      <input ref={оролтынRef} type="text" placeholder="Хайх..." />
      <button onClick={фокусТавих}>Хайлтанд очих</button>
    </div>
  );
}

Тоо эсвэл мутабел утга хадгалахад ч useRef хэрэглэнэ:

tsx
function Хугацаа() {
  // DOM биш — тоо хадгалах
  const интервалRef = useRef<ReturnType<typeof setInterval> | null>(null);

  const эхлэх = () => {
    интервалRef.current = setInterval(() => {
      console.log("тик...");
    }, 1000);
  };

  const зогсоох = () => {
    if (интервалRef.current) {
      clearInterval(интервалRef.current);
    }
  };

  return (
    <div>
      <button onClick={эхлэх}>Эхлэх</button>
      <button onClick={зогсоох}>Зогсоох</button>
    </div>
  );
}

Дараагийн хичээлд:

React Event-үүдийг — onClick, onChange, onSubmit — TypeScript-ээр хэрхэн зөв тодорхойлох тухай сурна.