React / useState hook

useState hook

Props ашиглан өгөгдөл дамжуулж сурлаа — гэхдээ props бол read-only, өөрчилж болохгүй. Харин апп ажиллаж байхад өгөгдөл өөрчлөгдөх ёстой: товч дарах тоолуур нэмэгдэх, форм бөглөхөд утга өөрчлөгдөх, нэвтрэх хүсэлт илгээхэд loading харагдах. Энэ бүхний хариулт бол state юм. useState hook нь component дотор өгөгдөл хадгалж, өөрчлөх боломж олгодог.

useState гэж юу вэ?

useState бол React-н built-in hook юм. Hook гэдэг нь use үгээр эхэлдэг, React-н онцгой функцуудыг хэлнэ. useState-г ашиглахын тулд эхлээд import хийнэ:

jsx
import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Тоо: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

useState(0) нь хоёр зүйл буцаана — array destructuring ашиглан авна:

  • count — одоогийн утга (эхлэх утга нь 0)
  • setCount — утгыг өөрчлөх функц

setCount дуудах бүрт React component-г дахин рендер хийж шинэ утгыг дэлгэцэнд харуулна.

State өөрчлөх дүрэм

State-г зөвхөн setter функцээр өөрчлөх ёстой — шууд өөрчилж болохгүй:

jsx
function Example() {
  const [score, setScore] = useState(0);

  function addPoints() {
    // ❌ Буруу — шууд өөрчилж байна, React мэдэхгүй
    score = score + 10;

    // ✅ Зөв — setter ашиглана
    setScore(score + 10);
  }

  return (
    <div>
      <p>Оноо: {score}</p>
      <button onClick={addPoints}>+10 оноо</button>
    </div>
  );
}

setScore дуудагдахад React дотооддоо шинэ утгыг хадгалж, component-г дахин рендер хийнэ. Шууд өөрчилвөл React үүнийг мэдэхгүй тул дэлгэц шинэчлэгдэхгүй.

Олон State хувьсагч

Нэг component дотор хэдэн ч useState ашиглаж болно:

jsx
function LoginForm() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [isLoading, setIsLoading] = useState(false);

  function handleSubmit() {
    setIsLoading(true);
    console.log("Нэвтрэж байна...", email);
    // API дуудалт хийнэ...
  }

  return (
    <div>
      <input
        type="email"
        value={email}
        placeholder="И-мэйл"
        onChange={(e) => setEmail(e.target.value)}
      />
      <input
        type="password"
        value={password}
        placeholder="Нууц үг"
        onChange={(e) => setPassword(e.target.value)}
      />
      <button onClick={handleSubmit} disabled={isLoading}>
        {isLoading ? "Ачааллаж байна..." : "Нэвтрэх"}
      </button>
    </div>
  );
}

Input-н value props болон onChange handler-г хослуулснаар React controlled component болдог — inputын утгыг React удирддаг болно.

Object ба Array State

State-д string, number-оос гадна object болон array ч хадгалж болно:

jsx
function TaskList() {
  const [tasks, setTasks] = useState([
    { id: 1, text: "React сурах", done: false },
    { id: 2, text: "Төсөл хийх", done: false },
  ]);

  function toggleTask(id) {
    // ✅ Зөв — шинэ array үүсгэж setter-д дамжуулна
    setTasks(
      tasks.map((task) =>
        task.id === id ? { ...task, done: !task.done } : task,
      ),
    );
  }

  return (
    <ul>
      {tasks.map((task) => (
        <li
          key={task.id}
          onClick={() => toggleTask(task.id)}
          style={{ textDecoration: task.done ? "line-through" : "none" }}
        >
          {task.text}
        </li>
      ))}
    </ul>
  );
}

Object эсвэл array state-г өөрчлөхдөө шинэ утга үүсгэнэ... spread оператор ихэвчлэн ашиглагддаг. React хуучин ба шинэ утгыг харьцуулан өөрчлөлт гарсан эсэхийг шалгадаг тул шинэ утга зайлшгүй хэрэгтэй.

Functional Update

Шинэ state нь хуучин state-с хамааралтай бол functional update хэлбэр ашиглах нь найдвартай:

jsx
function SafeCounter() {
  const [count, setCount] = useState(0);

  function increment() {
    // ✅ Найдвартай арга — өмнөх утгыг параметрээр авна
    setCount((prev) => prev + 1);
  }

  function incrementThree() {
    // Гурван удаа дуудахад зөв ажиллана
    setCount((prev) => prev + 1);
    setCount((prev) => prev + 1);
    setCount((prev) => prev + 1);
  }

  return (
    <div>
      <p>Тоо: {count}</p>
      <button onClick={increment}>+1</button>
      <button onClick={incrementThree}>+3</button>
    </div>
  );
}

prev => prev + 1 хэлбэрт setter функц хамгийн сүүлийн state утгыг параметрт авдаг тул олон шинэчлэлт зэрэг хийх үед алдаа гардаггүй.

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

Товч дарах, input бөглөх, маусаар хөдөлгөх зэрэг event handler бичих аргыг судална. onClick, onChange, onSubmit гэх мэт React-н event-уудтай гүнзгийрч танилцана.