Controlled Component — input, select, textarea bilan ishlash

~20 daq · React · Component Patterns

Muammo: input ning ikkita "egaligi"

Oddiy HTML da input o'z qiymatini o'zi saqlaydi. Brauzer boshqaradi. React da esa state bor — u ham qiymatni saqlaydi. Ikki joy bir xil ma'lumotni saqlasa — qaysi biri "haqiqiy"?

Controlled Component — input ning qiymatini React state boshqaradi. Foydalanuvchi yozganda state yangilanadi, state yangilanganda input yangilanadi. Bitta manba — state.

Foydalanuvchi yozdi
        │
        ▼
onChange ishladi → setState(yangiQiymat)
        │
        ▼
State yangilandi → input qayta chizildi
        │
        ▼
input.value = state  ← React boshqaradi

Asosiy misol

function Forma() {
  const [ism, setIsm] = useState('');

  return (
    <div>
      <input
        value={ism}           // state dan oladi
        onChange={e => setIsm(e.target.value)}  // state ni yangilaydi
        placeholder="Ismingiz"
      />
      <p>Siz yozdingiz: {ism}</p>
    </div>
  );
}

value={ism} — input ning qiymati har doim ism state ga teng. onChange — foydalanuvchi yozganda ism ni yangilaydi.

Agar onChange bo'lmasa — input "qotib" qoladi. Yozib bo'lmaydi. Chunki value state ga bog'liq, state o'zgarmayapti.


Barcha input turlari

Text, email, password, number

function RoyxatdanOtish() {
  const [forma, setForma] = useState({
    ism: '',
    email: '',
    parol: '',
    yosh: '',
  });

  // Bitta handler — maydon nomini dinamik ishlatish
  function ozgartir(e) {
    setForma({ ...forma, [e.target.name]: e.target.value });
  }

  return (
    <form>
      <input name="ism" value={forma.ism} onChange={ozgartir} placeholder="Ism" />
      <input name="email" type="email" value={forma.email} onChange={ozgartir} placeholder="Email" />
      <input name="parol" type="password" value={forma.parol} onChange={ozgartir} placeholder="Parol" />
      <input name="yosh" type="number" value={forma.yosh} onChange={ozgartir} placeholder="Yosh" />
    </form>
  );
}

[e.target.name] — computed property. name="ism" bo'lsa forma.ism ni yangilaydi, name="email" bo'lsa forma.email ni.

Checkbox

function Sozlamalar() {
  const [bildirishnoma, setBildirishnoma] = useState(false);
  const [yangiliklar, setYangiliklar] = useState(true);

  return (
    <div>
      <label>
        <input
          type="checkbox"
          checked={bildirishnoma}           // value emas — checked
          onChange={e => setBildirishnoma(e.target.checked)}  // value emas — checked
        />
        Bildirishnomalar
      </label>

      <label>
        <input
          type="checkbox"
          checked={yangiliklar}
          onChange={e => setYangiliklar(e.target.checked)}
        />
        Yangiliklar
      </label>
    </div>
  );
}

Checkbox da value emas — checked ishlatiladi. e.target.checked — true yoki false.

Select (dropdown)

function TilTanlash() {
  const [til, setTil] = useState('uz');

  return (
    <select value={til} onChange={e => setTil(e.target.value)}>
      <option value="uz">O'zbek</option>
      <option value="ru">Русский</option>
      <option value="en">English</option>
    </select>
  );
}

Textarea

function IzohForma() {
  const [izoh, setIzoh] = useState('');

  return (
    <textarea
      value={izoh}
      onChange={e => setIzoh(e.target.value)}
      rows={4}
      placeholder="Izohingizni yozing..."
    />
  );
}

Validatsiya

Controlled component ning kuchi — har yozilganda tekshirish mumkin:

function EmailInput() {
  const [email, setEmail] = useState('');
  const [xato, setXato] = useState('');

  function tekshir(qiymat) {
    setEmail(qiymat);
    if (!qiymat) {
      setXato('Email kiritilmadi');
    } else if (!qiymat.includes('@')) {
      setXato('Email noto\'g\'ri formatda');
    } else {
      setXato('');
    }
  }

  return (
    <div>
      <input
        type="email"
        value={email}
        onChange={e => tekshir(e.target.value)}
        style={{ borderColor: xato ? 'red' : 'green' }}
      />
      {xato && <p style={{ color: 'red' }}>{xato}</p>}
    </div>
  );
}

Tez-tez uchraydigan xatolar

value bor, onChange yo'q:

// ❌ Input qotib qoladi — yozib bo'lmaydi
<input value={ism} />

// ✅ onChange ham bo'lishi kerak
<input value={ism} onChange={e => setIsm(e.target.value)} />

value ga undefined berish:

const [ism, setIsm] = useState(); // undefined!

// ❌ undefined → controlled → uncontrolled o'tish — xato
<input value={ism} onChange={...} />

// ✅ Har doim boshlang'ich qiymat bering
const [ism, setIsm] = useState('');

React value={undefined} ni "controlled emas" deb o'ylaydi. Keyin qiymat kelganda "uncontrolled dan controlled ga o'tish" xatosi chiqadi.


Xulosa

Controlled Component — input qiymati React state da saqlanadi.

value={state}          → state dan o'qiydi
onChange → setState()  → state ni yangilaydi

Turlar:
  text/email/password → value + onChange (e.target.value)
  checkbox            → checked + onChange (e.target.checked)
  select              → value + onChange (e.target.value)
  textarea            → value + onChange (e.target.value)

Keyingi dars

29-dars: Uncontrolled Component — useRef bilan, qachon kerak