React: ro'yxat chizish va key

Props darsida TaskList ichida uchta TaskItem ni qo’lda yozdik. Vazifalar serverdan kelsa yoki foydalanuvchi yangisini qo’shsa, bu usul ishlamaydi — nechta element bo’lishini oldindan bilmaysiz. Ro’yxat ma’lumotdan hosil qilinishi kerak.

map — massivdan JSX massiviga

JSX darsida bitta fakt aytilgan edi: JSX — oddiy qiymat, va massiv {} ichida chizilganda elementlari ketma-ket joylashadi. Ikkalasini birlashtiramiz.

const tasks = [
  { id: 1, title: "Non olish", isDone: false },
  { id: 2, title: "Kitob o'qish", isDone: true },
  { id: 3, title: "Xat yozish", isDone: false },
];

function TaskList() {
  return (
    <ul>
      {tasks.map((task) => (
        <li key={task.id}>{task.title}</li>
      ))}
    </ul>
  );
}

export default TaskList;

Ekranda:

• Non olish
• Kitob o'qish
• Xat yozish

Bu massiv metodlari darsidagi map ning o’zi. Faqat natija son yoki matn emas, JSX elementi:

// map obyektlar massivini JSX massiviga aylantiradi
[{id: 1, ...}, {id: 2, ...}]  →  [<li>...</li>, <li>...</li>]

React massivni ko’rib, elementlarni ketma-ket chizadi.

Komponent bilan birga

Amalda <li> o’rniga tayyor komponent chiziladi:

// src/components/TaskList.jsx
import TaskItem from './TaskItem.jsx';

function TaskList({ tasks }) {
  return (
    <ul>
      {tasks.map((task) => (
        <TaskItem key={task.id} title={task.title} isDone={task.isDone} />
      ))}
    </ul>
  );
}

export default TaskList;
// src/App.jsx
import TaskList from './components/TaskList.jsx';

const tasks = [
  { id: 1, title: "Non olish", isDone: false },
  { id: 2, title: "Kitob o'qish", isDone: true },
  { id: 3, title: "Xat yozish", isDone: false },
];

function App() {
  return (
    <div>
      <h1>Vazifalar</h1>
      <TaskList tasks={tasks} />
    </div>
  );
}

export default App;

Ma’lumot App da turadi, TaskList uni props orqali oladi va har element uchun TaskItem chizadi. Brauzerda uchta vazifa ko’rinadi, ikkinchisi bajarilgan ko’rinishda.

key nega kerak

key ni tushirib qoldirsangiz ro’yxat baribir chiziladi, lekin brauzer konsolida ogohlantirish paydo bo’ladi:

Each child in a list should have a unique "key" prop.

Sababni tushunish uchun React qanday ishlashini eslang: ma’lumot o’zgarganda u yangi ko’rinishni eskisi bilan solishtiradi va DOM’da faqat farqni o’zgartiradi.

Ro’yxatda savol tug’iladi: yangi ro’yxatdagi uchinchi element eskisidagi uchinchi elementning o’zimi, yoki boshqami? key shu savolga javob beradi — u elementning shaxsiy belgisi.

key shartlari:

  • Noyob — bir ro’yxat ichida takrorlanmaydi;
  • Barqaror — chizishdan chizishga o’zgarmaydi;
  • Massiv elementiga tegishli — odatda id.

key ni map ichidagi eng tashqi elementga qo’ying:

// ✅ To'g'ri — key TaskItem da
{tasks.map((task) => <TaskItem key={task.id} task={task} />)}

// ❌ Noto'g'ri — key komponent ichidagi <li> da
function TaskItem({ task }) {
  return <li key={task.id}>{task.title}</li>;
}

Ikkinchi holatda React map natijasida key ni ko’rmaydi va ogohlantirish qolaveradi.

Indeks key sifatida — nega yomon

Ma’lumotda id bo’lmasa, indeksni ishlatish oson yo’lga o’xshaydi:

// ❌ Ehtiyot bo'ling
{tasks.map((task, index) => (
  <TaskItem key={index} task={task} />
))}

Muammo shundaki, indeks elementga emas, o’ringa tegishli. Ro’yxat tartibi o’zgarsa, indeks boshqa elementga o’tib ketadi.

Aniq misolda ko’ramiz. Ro’yxat shunday:

Indeks (key) Vazifa
0 Non olish
1 Kitob o’qish
2 Xat yozish

Endi boshiga yangi vazifa qo’shildi:

Indeks (key) Vazifa
0 Sut olish
1 Non olish
2 Kitob o’qish
3 Xat yozish

React nuqtai nazaridan key={0} avval “Non olish” edi, endi “Sut olish”. Demak u yangi element qo’shilgan deb emas, birinchi elementning matni o’zgargan deb hisoblaydi. Qolgan hammasi ham “o’zgargan” bo’lib chiqadi.

Natija ikki xil zarar keltiradi:

  1. Sekinlik — bitta element qo’shish o’rniga hamma qatorni yangilaydi.
  2. Holat aralashib ketadi — bu jiddiyroq.

Indeks qachon yaraydi:

  • ro’yxat hech qachon o’zgarmasa (tartib, qo’shish, o’chirish yo’q);
  • elementlarda holat va forma maydoni bo’lmasa.

Ikkalasiga ham ishonch bo’lmasa, id ishlating.

id qayerdan olinadi

Ma’lumot serverdan kelsa, id odatda bor bo’ladi. O’zingiz yaratsangiz:

const newTask = {
  id: crypto.randomUUID(),
  title: "Yangi vazifa",
  isDone: false,
};

crypto.randomUUID() — brauzerda mavjud funksiya, har chaqiruvda noyob matn qaytaradi:

"3f2b8c1e-9d4a-4f7b-8e1c-5a6d7b8c9e0f"

Date.now() ham ishlatiladi, lekin bir millisoniyada ikkita element qo’shilsa ikkalasida bir xil raqam chiqadi. crypto.randomUUID() xavfsizroq.

Bo’sh ro’yxat

Massiv bo’sh bo’lsa map bo’sh massiv qaytaradi va ekranda hech nima ko’rinmaydi. Foydalanuvchiga tushuntirish bergan yaxshi:

function TaskList({ tasks }) {
  if (tasks.length === 0) {
    return <p>Hozircha vazifa yo'q. Birinchisini qo'shing.</p>;
  }

  return (
    <ul>
      {tasks.map((task) => (
        <TaskItem key={task.id} task={task} />
      ))}
    </ul>
  );
}

Bo’sh massiv bilan chaqirilganda ro’yxat o’rniga xabar chiqadi. Shartli ko’rinishning boshqa usullarini shartli ko’rinish darsida ko’rasiz.

filter bilan birga

map dan oldin filter qo’yish mumkin — faqat kerakli elementlar chiziladi:

function TaskList({ tasks }) {
  const activeTasks = tasks.filter((task) => !task.isDone);

  return (
    <ul>
      {activeTasks.map((task) => (
        <TaskItem key={task.id} task={task} />
      ))}
    </ul>
  );
}

Bu yerda faqat bajarilmagan vazifalar ko’rinadi — yuqoridagi uchta vazifadan ikkitasi.

Amaliy mashq

  1. App.jsx da beshta vazifadan iborat tasks massivini yarating, har birida id, title va isDone bo’lsin.
  2. TaskList ni map bilan yozing va key={task.id} bering.
  3. key ni olib tashlang, brauzer konsolini oching va ogohlantirishni o’qing. Keyin qaytaring.
  4. map ichidagi arrow funksiyani jingalak qavsga o’rab, return ni ataylab yozmang — ro’yxat yo’qolganini ko’ring, keyin tuzating.
  5. filter qo’shib faqat bajarilmagan vazifalarni chizing va ekranda nechta qator qolganini sanang.
  6. tasks ni bo’sh massivga almashtiring va “vazifa yo’q” xabari chiqishini tekshiring.

3-va 4-qadamlar ikki eng ko’p uchraydigan holatni ko’rsatadi: birinchisi ogohlantirish beradi, ikkinchisi hech nima demaydi — shuning uchun ikkinchisini topish qiyinroq.

Qisqacha xulosa

  • Ro’yxat map bilan chiziladi: massiv elementlari JSX elementlariga aylanadi.
  • Arrow funksiyada jingalak qavs ishlatsangiz return majburiy — aks holda ro’yxat bo’sh chiqadi.
  • key React’ga elementni chizishlar orasida tanishga yordam beradi; u noyob va barqaror bo’lishi kerak.
  • key ni map ichidagi eng tashqi elementga qo’ying, komponent ichidagi tegga emas.
  • Indeksni key sifatida ishlatish ro’yxat tartibi o’zgarganda holat va forma maydonlarining aralashib ketishiga olib keladi.
  • id ni element yaratilayotganda bir marta hosil qiling — crypto.randomUUID() ishlaydi; Math.random() ni key ichida yozmang.
  • Bo’sh massiv uchun alohida xabar chiqarish foydalanuvchiga aniqlik beradi.

Keyingi darsda hodisalar: onClick va onChange — foydalanuvchi bosganda nima bo’lishi.

Bu dars foydali bo'ldimi?

marta ko'rildi