React

Ro'yxatlar va formalar

Real ilovalar ro'yxatlar (foydalanuvchilar, mahsulotlar, vazifalar) va formalar (matn kiritish, tanlash) bilan to'la. Ushbu yakuniy darsda massivni ekranga chiqarish, shartli ko'rsatish va formani boshqarishni o'rganib, kichik TODO ilovasini yig'amiz.

Massivni map bilan render qilish

React'da massivni ekranga chiqarish uchun JavaScript'ning Array.map() metodidan foydalanamiz. map har bir elementni JSX'ga aylantirib, JSX elementlari massivini qaytaradi. React esa bunday massivni avtomatik ravishda ketma-ket chizadi:

function Mevalar() {
  const mevalar = ["olma", "banan", "uzum"];
  return (
    <ul>
      {mevalar.map(meva => <li>{meva}</li>)}
    </ul>
  );
}

Bu yerda {mevalar.map(...)} uch dona <li> hosil qiladi. Ko'pincha obyektlar massivi bilan ishlaymiz:

function Foydalanuvchilar() {
  const users = [
    { id: 1, ism: "Ali" },
    { id: 2, ism: "Vali" },
    { id: 3, ism: "Guli" }
  ];
  return (
    <ul>
      {users.map(u => <li>{u.ism}</li>)}
    </ul>
  );
}

key propi โ€” nega u kerak?

Yuqoridagi kodni ishga tushirsangiz, React konsolda ogohlantirish beradi: "Each child in a list should have a unique key prop". Har bir ro'yxat elementiga key nomli maxsus prop berish shart:

{users.map(u => <li key={u.id}>{u.ism}</li>)}

key โ€” React'ga ro'yxatdagi har bir elementni farqlash imkonini beradigan noyob belgi. Nega u muhim? Ro'yxat o'zgarganda (element qo'shilsa, o'chirilsa, tartibi o'zgarsa), React key orqali qaysi element o'zgarganini aniq biladi va faqat shuni yangilaydi. Bu โ€” samaradorlik uchun juda muhim.

Massiv indeksini (map((item, i) => ... key={i})) key sifatida ishlatishdan iloji boricha qoching โ€” ro'yxat tartibi o'zgarganda bu xatolarga olib keladi. Har doim barqaror, noyob iddan foydalaning.

Shartli render โ€” && operatori

Ko'pincha biror elementni faqat ma'lum shartda ko'rsatishni istaymiz. JSX ichida if yozib bo'lmaydi, lekin && (mantiqiy VA) operatoridan foydalanish mumkin. Uning ishlashi: agar chap tomon true bo'lsa, o'ng tomondagi JSX ko'rsatiladi:

function Xabar({ xabarlarSoni }) {
  return (
    <div>
      <h1>Pochta</h1>
      {xabarlarSoni > 0 && (
        <p>Sizda {xabarlarSoni} ta yangi xabar bor</p>
      )}
    </div>
  );
}

Agar xabarlarSoni 0 dan katta bo'lsa, xabar ko'rsatiladi; aks holda hech narsa chiqmaydi. Chunki false && ... hech narsa render qilmaydi.

Ehtiyot bo'ling: {xabarlarSoni && ...} deb yozsangiz va son 0 bo'lsa, ekranda 0 raqami chiqib qoladi! Sababi: 0 โ€” "falsy", lekin React uni chizadi. Shuning uchun aniq shart yozing: {xabarlarSoni > 0 && ...}.

Shartli render โ€” ternar operator

Agar shartga qarab ikki xil narsadan birini ko'rsatish kerak bo'lsa (u yoki bu), ternar operator (shart ? a : b) ishlatiladi:

function Holat({ tizimgaKirgan }) {
  return (
    <div>
      {tizimgaKirgan
        ? <p>Xush kelibsiz!</p>
        : <p>Iltimos, tizimga kiring</p>}
    </div>
  );
}

Bu yerda tizimgaKirgan true bo'lsa birinchi, false bo'lsa ikkinchi <p> ko'rsatiladi. Ternar operator โ€” JSX ichida "agar-bo'lmasa" mantig'ini ifodalashning eng qulay usuli.

Qoida: bir narsa ko'rsatilishi yoki ko'rsatilmasligi kerak bo'lsa โ€” && ishlating. Ikkitadan biri ko'rsatilishi kerak bo'lsa โ€” ternar ishlating.

Controlled input โ€” boshqariladigan maydon

Formalar bilan ishlashda React'da controlled input (boshqariladigan maydon) uslubi qo'llaniladi. Bunda input maydonining qiymati state'da saqlanadi, ya'ni React โ€” yagona haqiqat manbasi. Bu ikki qadamdan iborat:

import { useState } from "react";

function Forma() {
  const [matn, setMatn] = useState("");

  return (
    <div>
      <input
        value={matn}
        onChange={e => setMatn(e.target.value)}
      />
      <p>Siz yozdingiz: {matn}</p>
    </div>
  );
}

Bu yerda oqim shunday: foydalanuvchi yozadi โ†’ onChange ishga tushadi โ†’ e.target.value orqali yangi qiymat olinadi โ†’ setMatn state'ni yangilaydi โ†’ React qayta render qiladi โ†’ value={matn} yangi qiymatni ko'rsatadi. Ma'lumot va ko'rinish doim mos bo'ladi.

e.target.value โ€” bu foydalanuvchi kiritgan input maydonining joriy matnini beradi. Bu โ€” oddiy DOM'dagi kabi ishlaydi.

To'liq TODO ilovasi

Endi o'rganganlarimizni birlashtirib, oddiy TODO (vazifalar ro'yxati) ilovasini yig'amiz. Unda: input orqali yangi vazifa qo'shish, ro'yxatni map bilan chiqarish, key ishlatish va shartli render bor:

import { useState } from "react";

function Todo() {
  const [matn, setMatn] = useState("");
  const [vazifalar, setVazifalar] = useState([]);

  function qoshish() {
    if (matn.trim() === "") return;
    const yangi = { id: Date.now(), text: matn };
    setVazifalar([...vazifalar, yangi]);
    setMatn("");
  }

  function ochirish(id) {
    setVazifalar(vazifalar.filter(v => v.id !== id));
  }

  return (
    <div>
      <h2>Vazifalar</h2>
      <input
        value={matn}
        onChange={e => setMatn(e.target.value)}
      />
      <button onClick={qoshish}>Qo'shish</button>

      {vazifalar.length === 0
        ? <p>Hozircha vazifa yo'q</p>
        : (
          <ul>
            {vazifalar.map(v => (
              <li key={v.id}>
                {v.text}
                <button onClick={() => ochirish(v.id)}>x</button>
              </li>
            ))}
          </ul>
        )}
    </div>
  );
}

export default Todo;

Ushbu ilova React asoslarining barchasini bir joyda ko'rsatadi:

State massivini hech qachon to'g'ridan-to'g'ri o'zgartirmang: vazifalar.push(yangi) ishlamaydi! Har doim yangi massiv yarating: setVazifalar([...vazifalar, yangi]). Bu โ€” React'ning holat o'zgarmasligi (immutability) qoidasi.

Forma va onSubmit

Yuqoridagi misolda tugma bosdik. Amalda formalarni <form> teg va onSubmit bilan yozish yaxshiroq โ€” chunki foydalanuvchi Enter tugmasi bilan ham yubora oladi. Faqat brauzerning sahifani qayta yuklashini e.preventDefault() bilan to'xtatish kerak:

function Forma() {
  const [matn, setMatn] = useState("");

  function yuborish(e) {
    e.preventDefault(); // sahifa qayta yuklanmasin
    console.log("Yuborildi:", matn);
    setMatn("");
  }

  return (
    <form onSubmit={yuborish}>
      <input value={matn} onChange={e => setMatn(e.target.value)} />
      <button type="submit">Yuborish</button>
    </form>
  );
}
e.preventDefault()ni unutmang โ€” aks holda forma yuborilganda brauzer sahifani qayta yuklaydi va SPA "buziladi".

Xulosa