React forma va boshqariladigan elementlar

useState darsida “Qo’shish” tugmasi har doim bir xil matnli vazifa qo’shardi. Foydalanuvchi o’z matnini yozishi kerak. Bu darsda React’da forma bilan ishlashni ko’ramiz.

Boshqariladigan element

React’da forma maydoni holat bilan bog’lanadi. Ikki narsa birga beriladi:

import { useState } from 'react';

function SearchBox() {
  const [query, setQuery] = useState("");

  return (
    <div>
      <input
        type="text"
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        placeholder="Qidirish"
      />
      <p>Qidirilmoqda: {query}</p>
    </div>
  );
}

export default SearchBox;

Maydonga yozing — pastdagi matn bir vaqtda o’zgaradi.

Aylanish shunday:

  1. Foydalanuvchi harf yozadi.
  2. onChange ishlaydi va setQuery ni chaqiradi.
  3. Holat o’zgaradi, komponent qayta chiziladi.
  4. value={query} yangi qiymatni maydonga qo’yadi.

Bir qarashda ortiqcha aylanish ko’rinadi, lekin foydasi katta: qiymat har doim holatda turadi. Uni tekshirish, o’zgartirish yoki tozalash uchun DOM’dan o’qish kerak emas.

value bor, onChange yo’q

Faqat value bersangiz maydon qotib qoladi — yozib bo’lmaydi:

// ❌ Maydon faqat o'qish uchun bo'lib qoladi
<input type="text" value={query} />

Brauzer konsolida:

You provided a `value` prop to a form field without an `onChange`
handler. This will render a read-only field.

Boshlang’ich qiymat undefined bo’lmasin

Yana bir tuzoq — holatni undefined bilan boshlash:

// ❌ Muammo tug'diradi
const [query, setQuery] = useState();

// ✅ Bo'sh matn bilan
const [query, setQuery] = useState("");

Birinchi holatda maydon avval boshqarilmaydigan bo’lib boshlanadi, keyin matn kiritilganda boshqariladiganga aylanadi. React bu haqda ogohlantiradi:

A component is changing an uncontrolled input to be controlled.

Matn maydonlari uchun boshlang’ich qiymat doim "" bo’lsin.

onSubmit va preventDefault

Formani yuborishni tugma onClick orqali emas, <form> ning onSubmit orqali ushlang — shunda Enter bosilganda ham ishlaydi:

import { useState } from 'react';

function TaskForm() {
  const [title, setTitle] = useState("");

  function handleSubmit(e) {
    e.preventDefault();

    if (title.trim() === "") {
      return;
    }

    console.log("Yangi vazifa:", title);
    setTitle("");
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={title}
        onChange={(e) => setTitle(e.target.value)}
        placeholder="Vazifa nomi"
      />
      <button type="submit">Qo'shish</button>
    </form>
  );
}

export default TaskForm;

Maydonga “Non olish” yozib Enter bosing. Konsolda:

Yangi vazifa: Non olish

Maydon esa bo’shab qoladi — setTitle("") shuni qiladi.

title.trim() === "" tekshiruvi ham muhim: bo’sh yoki faqat probeldan iborat vazifa qo’shilishining oldini oladi.

Bir nechta maydon

Har maydon uchun alohida useState yozish mumkin:

const [title, setTitle] = useState("");
const [priority, setPriority] = useState("normal");
const [isUrgent, setIsUrgent] = useState(false);

Maydon uch-to’rttagacha bo’lsa bu yaxshi ishlaydi. Ko’paysa, bitta obyekt qulayroq:

import { useState } from 'react';

function TaskForm() {
  const [form, setForm] = useState({
    title: "",
    priority: "normal",
    isUrgent: false,
  });

  function handleChange(e) {
    const { name, value, type, checked } = e.target;
    setForm({
      ...form,
      [name]: type === "checkbox" ? checked : value,
    });
  }

  function handleSubmit(e) {
    e.preventDefault();
    console.log("Forma:", form);
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        name="title"
        value={form.title}
        onChange={handleChange}
        placeholder="Vazifa nomi"
      />

      <select name="priority" value={form.priority} onChange={handleChange}>
        <option value="low">Past</option>
        <option value="normal">O'rtacha</option>
        <option value="high">Yuqori</option>
      </select>

      <label htmlFor="isUrgent">
        <input
          id="isUrgent"
          type="checkbox"
          name="isUrgent"
          checked={form.isUrgent}
          onChange={handleChange}
        />
        Shoshilinch
      </label>

      <button type="submit">Saqlash</button>
    </form>
  );
}

export default TaskForm;

Maydonlarni to’ldirib “Saqlash” bosing:

Forma: { title: "Non olish", priority: "high", isUrgent: true }

Bitta handleChange barcha maydonga xizmat qiladi. Uchta joyga e’tibor bering:

  • name atributi obyektdagi kalit bilan bir xil;
  • [name]: ... — hisoblanadigan kalit (obyektlar darsidagi sintaksis);
  • type === "checkbox" — checkbox uchun value emas, checked o’qiladi.

Maydon turlari

Har element o’z props’i bilan bog’lanadi:

Element Bog’lanish Qiymat o’qish
<input type="text"> value e.target.value
<input type="number"> value e.target.value (matn)
<input type="checkbox"> checked e.target.checked
<input type="radio"> checked e.target.value
<select> value e.target.value
<textarea> value e.target.value

Ikki farq HTML’ga nisbatan:

// HTML'da tarkib ichida, React'da value props
<textarea value={text} onChange={handleChange} />

// HTML'da <option selected>, React'da <select value>
<select value={priority} onChange={handleChange}>
  <option value="low">Past</option>
  <option value="high">Yuqori</option>
</select>

Formani tekshirish

Xatoni holatda saqlab, foydalanuvchiga ko’rsating:

import { useState } from 'react';

function TaskForm() {
  const [title, setTitle] = useState("");
  const [error, setError] = useState("");

  function handleSubmit(e) {
    e.preventDefault();

    if (title.trim().length < 3) {
      setError("Vazifa nomi kamida 3 belgidan iborat bo'lsin.");
      return;
    }

    setError("");
    console.log("Qabul qilindi:", title);
    setTitle("");
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={title}
        onChange={(e) => setTitle(e.target.value)}
        placeholder="Vazifa nomi"
      />
      {error && <p className="error">{error}</p>}
      <button type="submit">Qo'shish</button>
    </form>
  );
}

export default TaskForm;

Bo’sh maydon bilan yuborsangiz qizil yozuv chiqadi. Uch belgidan uzun matn kiritilsa xabar yo’qoladi va konsolga vazifa tushadi.

Forma asoslari darsidagi required va minlength atributlari ham qo’shimcha himoya beradi, lekin ular brauzerga bog’liq. Muhim tekshiruv har doim kodda takrorlanadi.

Amaliy mashq

  1. SearchBox komponentini yozing: maydonga kiritilgan matn pastda bir vaqtda ko’rinsin.
  2. onChange ni olib tashlang va maydonga yozib ko’ring. Konsoldagi ogohlantirishni o’qing, keyin qaytaring.
  3. TaskForm yozing: onSubmit va e.preventDefault() bilan, yuborilgandan keyin maydon bo’shasin.
  4. e.preventDefault() ni vaqtincha o’chirib Enter bosing — sahifa qayta yuklanganini kuzating.
  5. Formani kengaytiring: select (muhimlik) va checkbox (shoshilinch) qo’shing, uchalasini bitta obyekt holatida saqlang.
  6. handleChange ichidagi ...form ni o’chirib ko’ring va boshqa maydonlar qanday yo’qolishini kuzating.

4-va 6-qadamlar eng ko’p vaqt yo’qotadigan ikki xatoni ko’rsatadi — ikkalasi ham sabab tushunilmasa uzoq qidiriladi.

Qisqacha xulosa

  • Boshqariladigan element — qiymati holatda saqlanadigan maydon: value holatdan, onChange holatga.
  • value va onChange ajralmas — faqat value berilsa maydon qotib qoladi.
  • Matn holatini undefined emas, "" bilan boshlang.
  • e.preventDefault() bo’lmasa forma sahifani qayta yuklaydi.
  • Ko’p maydonni bitta obyektda saqlash mumkin; name atributi kalit bilan mos kelsin va ...form ni tushirib qoldirmang.
  • Checkbox checked bilan bog’lanadi va e.target.checked o’qiladi; type="number" esa matn qaytaradi.
  • Tekshiruv natijasini holatda saqlab, xabarni ekranda ko’rsating.

Keyingi darsda shartli ko’rinish — xato xabarini chiqarishda ishlatgan && naqshining to’liq qoidalari.

Bu dars foydali bo'ldimi?

marta ko'rildi