Mundarija (32)
- Bu darsda
- 1. Nega bu kerak?
- 2. Birinchi o'z komponentimiz
- 2.1 Bitta katta App dan bo'laklarga
- 2.2 Komponentni React chaqiradi
- 2.3 Arrow funksiya ham komponent
- 3. Komponent nimani qaytaradi
- 3.1 JSX, matn, son, null, massiv
- 3.2 return unutilsa
- 4. Nomlash: PascalCase
- 4.1 Kichik harf — HTML teg
- 4.2 Yaxshi nom qanday bo'ladi
- 5. Komponentlar daraxti
- 6. Komponentni alohida faylga chiqarish
- 6.1 Bir fayl — bir komponent
- 6.2 Named va default export
- 6.3 Import xatolari
- 6.4 Komponent faylida boshqa narsa eksport qilsa
- 7. Komponent ichida komponent e'lon qilmang
- 7.1 Tuzoqni jonli ko'ramiz
- 7.2 Nega yo'qoldi
- 7.3 Linter buni ushlaydi
- 8. Vazifalar qadami: ro'yxat komponentlari rejasi
- 9. Ko'p uchraydigan xatolar
- 10. Mashqlar
- 1-mashq (oson): uchta xato
- 2-mashq (o'rta): menyu sahifasini bo'laklang
- 3-mashq (qiyin): fayllarga ajrating va tuzoqni tuzating
- 4-mashq: Vazifalar qadami
- 11. Real ishda
- Xulosa
- Manbalar
Komponentlar: yaratish, nomlash va fayllarga ajratish — PascalCase, export va "ichma-ich komponent" tuzog'i
Qisqacha: React komponenti — JSX qaytaradigan oddiy funksiya, nomi katta harf bilan (PascalCase):
function MenuCard() { return <li>…</li>; }. Uni teg kabi ishlatasiz —<MenuCard />, chaqirishni React o'zi qiladi. Odatda har komponent o'z.tsxfaylida turadi vaexport function(named export) bilan chiqariladi. Komponentni boshqa komponent ichida e'lon qilmang: har chizishda u "yangi tur" bo'lib qoladi va React uning DOM'ini o'chirib, qaytadan yasaydi — yozilgan matn yo'qoladi.
Bu darsda
- Bir sahifani ma'noli bo'laklarga — komponentlarga — ajrata olasiz.
- Komponent nomini to'g'ri tanlaysiz va kichik harf nega ishlamasligini tushuntira olasiz.
- Komponentni alohida faylga chiqarasiz: named va default export farqini bilasiz, import xatolarini taniysiz.
- Komponent nimani qaytara olishini bilasiz: JSX,
null, matn, son, massiv. - "Komponent ichida komponent" tuzog'ini jonli ko'rib, uni lint qoidasi bilan ushlaysiz.
Oldin bilishingiz kerak: JSX II: ifodalar, Fragment va nima ekranga chiqadi, JSX I: JSX aslida JavaScript, Nega modullar va ESM export.
1. Nega bu kerak?
JSX II darsida hamma kodni bitta App ichiga yozdik. Kichik misolda bu qulay. Lekin «Bahor» saytining bosh sahifasini tasavvur qiling: sarlavha, ish vaqti, menyu, aloqa, pastki qism. Hammasi bitta funksiyada bo'lsa — 200 qatorli return. Qaysi qavs nimani yopayotganini topish qiyin, menyu kartasi o'n joyda takrorlanadi.
Vanilla'da bu muammoni allaqachon yechgansiz. vazifalar dagi render.ts da oddiyQator(), tahrirQatori(), tugmaYasa() funksiyalari bor. Har biri bitta bo'lakni yasab qaytaradi. Katta ekran — kichik funksiyalar yig'indisi.
React'da g'oya o'sha, faqat funksiya DOM elementini emas, JSX qaytaradi. Bunday funksiya komponent deyiladi. Hayotiy o'xshatish: oshxonadagi retseptlar daftari. Osh retsepti bir sahifada yozilgan, oshpaz uni har kuni qayta ishlatadi va har safar boshqatdan o'ylab topmaydi. Menyu kartasi ham shunday: bir marta yozasiz, kerakli joyga qo'yasiz.
2. Birinchi o'z komponentimiz
2.1 Bitta katta App dan bo'laklarga
Avval «Bahor» bosh sahifasi — hammasi bitta joyda:
function App() {
return (
<div>
<header>
<h1>«Bahor» oshxonasi</h1>
<p>Toshkent, Chilonzor</p>
</header>
<p>Ish vaqti: 07:00–23:00</p>
<footer>
<p>Tel: +998 90 000 00 00</p>
</footer>
</div>
);
}Ekranda:
«Bahor» oshxonasi
Toshkent, Chilonzor
Ish vaqti: 07:00–23:00
Tel: +998 90 000 00 00Endi har ma'noli bo'lakni o'z funksiyasiga olib chiqamiz:
function SiteHeader() {
return (
<header>
<h1>«Bahor» oshxonasi</h1>
<p>Toshkent, Chilonzor</p>
</header>
);
}
function WorkHours() {
return <p>Ish vaqti: 07:00–23:00</p>;
}
function SiteFooter() {
return (
<footer>
<p>Tel: +998 90 000 00 00</p>
</footer>
);
}
function App() {
return (
<div>
<SiteHeader />
<WorkHours />
<SiteFooter />
</div>
);
}Ekranda:
«Bahor» oshxonasi
Toshkent, Chilonzor
Ish vaqti: 07:00–23:00
Tel: +998 90 000 00 00Ekran o'zgarmadi — bu yaxshi belgi. Endi App ni o'qish oson: uch qator, uchta bo'lak. Sarlavhani o'zgartirmoqchi bo'lsangiz — SiteHeader ni ochasiz, qolganiga tegmaysiz.
Uch qoida ko'rinib turibdi:
- Komponent — oddiy
function, hech qanday maxsus kalit so'z yo'q. - U JSX qaytaradi —
returnbilan. - Uni teg kabi ishlatamiz:
<SiteHeader />. Ichida hech narsa bo'lmasa — o'zini yopuvchi teg (/>), JSX I dagidek.
2.2 Komponentni React chaqiradi
<SiteHeader /> yozganingizda SiteHeader hali chaqirilmaydi. JSX I darsida ko'rdik: bu jsx(SiteHeader, {}) ga aylanadi va oddiy obyekt yasaydi — type maydonida funksiyaning o'zi turadi. Funksiyani keyin React chaqiradi, ekranga chizish vaqti kelganda.
Farqni kod bilan ko'ramiz. console.log funksiya qachon ishlaganini ko'rsatadi:
function WorkHours() {
console.log("WorkHours chaqirildi");
return <p>Ish vaqti: 07:00–23:00</p>;
}
const element = <WorkHours />;
console.log("Element tayyor:", typeof element.type);
function App() {
return element;
}Konsolda:
Element tayyor: function
WorkHours chaqirildiEkranda:
Ish vaqti: 07:00–23:00Avval "Element tayyor" chiqdi: <WorkHours /> faqat "buyurtma qog'ozi" yasadi. "WorkHours chaqirildi" esa keyin — React App ni chizayotganda. Komponentni o'zingiz WorkHours() deb chaqirmang. Hozircha ekran bir xil chiqadi, lekin React uni alohida komponent deb tanimaydi. useState darsidan boshlab bu haqiqiy xatoga aylanadi (Hooklar qoidalari darsida sababi).
2.3 Arrow funksiya ham komponent
Komponent function bilan ham, arrow funksiya bilan ham yoziladi:
const WorkHours = () => <p>Ish vaqti: 07:00–23:00</p>;
function App() {
return <WorkHours />;
}Ekranda:
Ish vaqti: 07:00–23:00React uchun farqi yo'q. Bu kursda va vazifalar da function ishlatamiz. U faylning istalgan joyidan ko'rinadi (hoisting): App ni yuqoriga, yordamchi komponentlarni pastga yozish mumkin. React rasmiy hujjatlari ham function bilan yozadi.
Tekshirib ko'ring:
const a = <SiteHeader />;qatori bajarilgandaSiteHeaderfunksiyasi necha marta chaqiriladi?
Javob
Nol marta. JSX faqat element obyektini yasaydi: { type: SiteHeader, props: {} }. Funksiyani React chaqiradi — element ekranga chizilganda. Element hech qachon chizilmasa (masalan, o'zgaruvchida qolib ketsa), funksiya umuman chaqirilmaydi.
3. Komponent nimani qaytaradi
3.1 JSX, matn, son, null, massiv
Komponent qaytaradigan qiymatga JSX II dagi {} qoidalari amal qiladi. Ya'ni {} ichiga nima qo'ysangiz bo'lsa, komponent shuni qaytara oladi:
function Price() {
return 35000;
}
function Nothing() {
return null;
}
function Pair() {
return [<b key="osh">Osh</b>, " va ", <i key="choy">choy</i>];
}
function Greeting() {
return "Xush kelibsiz!";
}
function App() {
return (
<div>
<p><Price /> so'm</p>
<p>[<Nothing />]</p>
<p><Pair /></p>
<p><Greeting /></p>
</div>
);
}Ekranda:
35000 so'm
[]
Osh va choy
Xush kelibsiz!null — "bu komponent hozir hech narsa chizmaydi". Masalan, aksiya tugaganda aksiya bannerini yashirish uchun. Bu usulni Shartli render darsida ko'p ishlatamiz. Massiv o'rniga odatda Fragment yoziladi (<>…</>) — unda key kerak emas.
3.2 return unutilsa
Arrow funksiyadan function ga o'tganda ko'p uchraydigan xato:
function SiteHeader() {
<h1>«Bahor» oshxonasi</h1>;
}
function App() {
return (
<div>
<SiteHeader />
<p>Ish vaqti: 07:00–23:00</p>
</div>
);
}Ekranda:
Ish vaqti: 07:00–23:00Sarlavha yo'q, konsolda ham hech narsa yo'q. JSX hisoblandi va tashlab yuborildi, funksiya esa undefined qaytardi. React 19 undefined ni "hech narsa" deb qabul qiladi — xuddi null kabi. Shuning uchun bu xato jim o'tadi.
TypeScript esa uni ushlaydi:
function SiteHeader() {
<h1>«Bahor» oshxonasi</h1>;
}
export function App() {
return <SiteHeader />;
}Xato:
TS2786: 'SiteHeader' cannot be used as a JSX component.
Its type '() => void' is not a valid JSX element type.
Type '() => void' is not assignable to type '(props: any) => Promise<ReactNode> | ReactNode'.
Type 'void' is not assignable to type 'Promise<ReactNode> | ReactNode'.Tarjima: "SiteHeader ni JSX komponenti sifatida ishlatib bo'lmaydi. Uning turi — void (hech narsa) qaytaradigan funksiya." Oxirgi qator asosiysi: "void turini ReactNode ga berib bo'lmaydi". JSX II darsidagi ReactNode — komponent qaytarishi mumkin bo'lgan qiymatlar, void esa unda yo'q. Bu — vazifalar dagidek .tsx da yozishning yana bir foydasi.
Maslahat: Qavsli arrow funksiya
() => (<h1>…</h1>)JSX'ni o'zi qaytaradi. Jingalak qavsli() => { <h1>…</h1> }esa qaytarmaydi — xuddi yuqoridagi xato.
4. Nomlash: PascalCase
4.1 Kichik harf — HTML teg
React nima va nega darsida kichik harfli menuCard ni sinab ko'rgan edik. Natija — ekran bo'sh va konsolda ikki ogohlantirish:
function workHours() {
return <p>Ish vaqti: 07:00–23:00</p>;
}
function App() {
return <workHours />;
}Konsolda:
<workHours /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
The tag <workHours> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.Ekranda:
(bo'sh)Sababi transpilerda (JSX I): kichik harfli teg satrga aylanadi — jsx("workHours", {}). React brauzerdan <workhours> elementini so'radi. Bunday HTML teg yo'q — bo'sh noma'lum element chiqdi, funksiya esa umuman chaqirilmadi. Katta harfli <WorkHours /> esa o'zgaruvchiga aylanadi — jsx(WorkHours, {}).
4.2 Yaxshi nom qanday bo'ladi
PascalCase — har so'z katta harf bilan, orada bo'shliq va chiziqcha yo'q: MenuCard, SiteHeader, OrderList. Bundan tashqari:
| Qoida | ||
|---|---|---|
| Ot — "nima chiziladi" | OrderList |
RenderOrders, ShowList |
| Ma'noli, qisqartmasiz | WorkHours |
WH, Comp1 |
| Bo'lak nomi ota nomidan | MenuCard, MenuList |
Card2 |
| Fayl nomi = komponent nomi | MenuCard.tsx |
card.tsx |
Kursda funksiyalarni fe'l bilan nomlaymiz (narxniHisobla). Komponent esa istisno: u ishni bajarmaydi, ekran bo'lagini tasvirlaydi. Shuning uchun nomi — ot. vazifalar da komponent nomlari o'zbekcha: VazifaQatori, AmalTugmasi, VazifaRoyxati — qoida o'sha.
Tekshirib ko'ring: Qaysilari ishlaydi?
<Menu_card />,<MENU />,<menuCard />,<Menu2 />.
Javob
Kichik harfli <menuCard /> dan boshqa hammasi komponent sifatida ishlaydi: React faqat birinchi harfga qaraydi. Lekin Menu_card va MENU — PascalCase emas, kod ko'rigida qaytariladi. Menu2 ishlaydi, lekin ma'nosiz nom.
5. Komponentlar daraxti
Bo'laklar bir-birining ichiga joylashadi. «Bahor» menyu sahifasini daraxt qilib chizamiz:
flowchart TD
App --> SiteHeader
App --> MenuList
App --> SiteFooter
MenuList --> C1["MenuCard (Osh)"]
MenuList --> C2["MenuCard (Manti)"]
MenuList --> C3["MenuCard (Choy)"]Rasmga qarang: yuqorida App, undan pastga bolalari. Bu yerda App boshqa komponentlarni chizadi — u ularning ota komponenti (parent). Uning bola komponentlari (children) esa SiteHeader, MenuList va SiteFooter. Diqqat qiling: MenuCard uch marta uchraydi — bitta funksiya, uch nusxa. Bu daraxt DOM daraxti dan bir pog'ona yuqorida turadi: bitta MenuCard ichida bir nechta DOM elementi bo'lishi mumkin.
Daraxtning foydasi: ma'lumot yuqoridan pastga oqadi. Keyingi darsda MenuList har MenuCard ga o'z taomini props orqali beradi. Hozircha har bola o'z ichidagini o'zi biladi.
6. Komponentni alohida faylga chiqarish
6.1 Bir fayl — bir komponent
Birinchi React loyiha darsidagi bahor-menyu loyihasini davom ettiramiz. Kichik loyihada komponentlar src/ ichida, kattaroqda — src/components/ papkasida:
src/
├── main.tsx ← createRoot(...).render(<App />)
├── App.tsx ← sahifa: bo'laklarni yig'adi
└── components/
├── SiteHeader.tsx
├── WorkHours.tsx
└── SiteFooter.tsxHar fayl — bitta komponent va uning nomi bilan:
// src/components/WorkHours.tsx
export function WorkHours() {
return <p>Ish vaqti: 07:00–23:00</p>;
}App.tsx ularni import qilib yig'adi:
// src/App.tsx
import { SiteHeader } from "./components/SiteHeader.tsx";
import { WorkHours } from "./components/WorkHours.tsx";
import { SiteFooter } from "./components/SiteFooter.tsx";
export default function App() {
return (
<div>
<SiteHeader />
<WorkHours />
<SiteFooter />
</div>
);
}Bu ikki blokda «Ishga tushir» yo'q: ular bir-birini fayl orqali import qiladi, natija oynasi esa bitta blokni bajaradi. Shu fayllarni o'z loyihangizda yarating — npm run dev da ekran «Bitta katta App dan bo'laklarga» bo'limidagi bilan bir xil chiqadi.
Nega har komponent alohida faylda:
- Topish oson —
WorkHours.tsxnomidan ichida nima borligi ko'rinadi. - Git tarixi toza — sarlavha o'zgarsa, faqat bitta fayl o'zgaradi (git diff kichik va tushunarli).
- Fast Refresh ishlaydi (Birinchi React loyiha): faqat komponent eksport qiladigan fayl tahrirlanganda sahifa qayta yuklanmaydi.
6.2 Named va default export
Modullar darsidagi ikki xil export komponentlarda ham bor:
| Named export | Default export | |
|---|---|---|
| Yozilishi | export function MenuCard() |
export default function App() |
| Import | import { MenuCard } from "…" |
import App from "…" |
| Nom | aynan bir xil bo'lishi shart | import qiluvchi istagancha ataydi |
| Faylda | bir nechta bo'lishi mumkin | faqat bitta |
Vite shablonida App — default export. vazifalar da va bu kursda komponentlar — named export. Sababi: nom hamma joyda bir xil bo'ladi. Default bilan bir fayl import Card from …, boshqasi import MenuCard from … deb yozishi mumkin. Qidiruvda ikkalasini topish qiyin, nomini o'zgartirganda biri esdan chiqadi. Default export kerak bo'ladigan joylar ham bor: React.lazy va ba'zi framework'lar (Next.js sahifalari) shuni talab qiladi — ularga keyingi qismlarda yetamiz.
6.3 Import xatolari
Eng ko'p uchraydigani — named export'ni default kabi import qilish:
// src/App.tsx — ❌ MenuCard.tsx da "export function MenuCard"
import MenuCard from "./MenuCard.tsx";Uch joyda uch xil xabar chiqadi. Biz Vite shablonida haqiqatan sinab ko'rdik. npm run dev da brauzer konsolida (ekran bo'sh):
Uncaught SyntaxError: The requested module '/src/MenuCard.tsx' does not provide an export named 'default'"So'ralgan modul default nomli eksport bermaydi." npx tsc -b da (yo'l qisqartirilgan):
src/App.tsx(1,8): error TS2613: Module '".../src/MenuCard"' has no default export. Did you mean to use 'import { MenuCard } from ".../src/MenuCard"' instead?TypeScript hatto to'g'ri yozuvni ham taklif qiladi: "import { MenuCard } … demoqchimidingiz?". npm run build da Vite 8 (Rolldown):
[MISSING_EXPORT] "default" is not exported by "src/MenuCard.tsx".Tuzatish — jingalak qavslar: import { MenuCard } from "./MenuCard.tsx";. Teskari xato ham bor: default'ni { App } qilib import qilish. U holda xabarda export named 'App' deyiladi.
6.4 Komponent faylida boshqa narsa eksport qilsa
Shablondagi linter (Oxlint) bitta qoidani kuzatadi. MenuCard.tsx ga narx formatlaydigan funksiya qo'shib, uni ham eksport qildik:
export function MenuCard() {
return <li>Osh — {formatPrice(35000)}</li>;
}
export function formatPrice(price: number) {
return `${price} so'm`;
}npm run lint (Oxlint 1.87.0):
src/MenuCard.tsx:5:17: warning react(only-export-components): Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components."Fast Refresh faqat fayl komponentlarni eksport qilsagina ishlaydi. Komponentlar orasida umumiy konstanta yoki funksiyani yangi faylga oling." Bu xato emas, ogohlantirish: ilova ishlaydi, faqat shu faylni tahrirlaganda sahifa to'liq qayta yuklanadi. Yechim — formatPrice ni src/format.ts ga ko'chirish. .ts — chunki ichida JSX yo'q.
7. Komponent ichida komponent e'lon qilmang
7.1 Tuzoqni jonli ko'ramiz
Sardor ism maydonini alohida komponentga ajratdi va uni App ning ichiga yozdi — "u faqat shu yerda kerak-ku". Quyidagi blokda count va draw() — JSX II darsidagi vanilla usul: tugma count ni oshirib, App ni qayta chizadi. Blok o'zi maydonga "Ali" deb yozadi, keyin «+1» ni bosadi:
import { flushSync } from "react-dom";
import { createRoot } from "react-dom/client";
const root = createRoot(document.getElementById("root"));
let count = 0;
function App() {
// ❌ komponent App ichida e'lon qilingan
function NameField() {
return <input aria-label="Ism" />;
}
return (
<div>
<p>Bosildi: {count}</p>
<NameField />
<button onClick={draw}>+1</button>
</div>
);
}
function draw() {
count++;
flushSync(() => root.render(<App />));
const input = document.querySelector("input");
console.log("Maydonda:", JSON.stringify(input.value));
}
flushSync(() => root.render(<App />));Konsolda:
Maydonda: ""Ekranda:
Bosildi: 1
+1«Ishga tushir» ni bosing va o'zingiz sinang: maydonga yozing, «+1» ni bosing — matn yo'qoladi. Bu yerdagi flushSync — Birinchi React loyiha dagidek: chizishni darhol tugatadi, shunda keyingi qatordagi console.log yangi DOM'ni o'qiydi.
7.2 Nega yo'qoldi
Har App chaqiruvida function NameField() {…} qatori yangi funksiya yaratadi. Closure darsidan bilasiz: ikki marta yaratilgan funksiya — ikki xil obyekt, === bilan teng emas. React esa daraxtni solishtirganda avval elementning turiga (type) qaraydi:
| Qadam | NameField |
React qarori | Maydonda |
|---|---|---|---|
| birinchi chizish | funksiya №1 | yangi <input> yasaydi |
"" |
| "Ali" yozildi | — | — | "Ali" |
| «+1», qayta chizish | funksiya №2 | tur boshqa → eskisini o'chirib, yangisini yasaydi | "" |
"Tur boshqa" — React uchun "bu butunlay boshqa komponent". Eski <input> DOM'dan olib tashlanadi, o'rniga yangi, bo'sh <input> qo'yiladi. Fokus ham, yozilgan matn ham yo'qoladi. Keyingi darslarda komponentning o'z xotirasi (state) paydo bo'ladi — u ham har safar o'chadi.
Tuzatish — komponentni tashqariga, faylning yuqori darajasiga chiqarish:
import { flushSync } from "react-dom";
import { createRoot } from "react-dom/client";
const root = createRoot(document.getElementById("root"));
let count = 0;
// ✅ yuqori darajada: funksiya bir marta yaratiladi
function NameField() {
return <input aria-label="Ism" />;
}
function App() {
return (
<div>
<p>Bosildi: {count}</p>
<NameField />
<button onClick={draw}>+1</button>
</div>
);
}
function draw() {
count++;
flushSync(() => root.render(<App />));
const input = document.querySelector("input");
console.log("Maydonda:", JSON.stringify(input.value));
}
flushSync(() => root.render(<App />));Konsolda:
Maydonda: "Ali"Ekranda:
Bosildi: 1
+1Endi NameField — har safar o'sha bitta funksiya. React turni bir xil ko'radi va <input> ga tegmaydi. Bu xulqning to'liq ichki ishlashi — Reconciliation va Fiber darsida.
7.3 Linter buni ushlaydi
eslint-plugin-react-hooks 7.1.1 da bu holat uchun alohida qoida bor — react-hooks/static-components. Uni vazifalar ga Birinchi React loyiha darsida ulagan edik. Mana bunday faylni tekshirdik:
// Profile.jsx — ❌ Price komponenti Profile ichida
export function Profile({ dish }) {
function Price() {
return <b>{dish.price} so'm</b>;
}
return <Price />;
}npx eslint Profile.jsx (ESLint 10.12.0; kod parchalari qisqartirilgan, izoh qatori olib tashlangan):
6:11 error Error: Cannot create components during render
Components created during render will reset their state each time they are created. Declare components outside of render.
> 6 | return <Price />;
| ^^^^^ This component is created during render
> 3 | function Price() {
| ^^^^^^^^^^^^^^^^^^
…
> 5 | }
| ^^^^ The component is created during render here
react-hooks/static-components
✖ 1 problem (1 error, 0 warnings)"Render paytida komponent yaratib bo'lmaydi. Render vaqtida yaratilgan komponentlar har safar state'ini yo'qotadi. Komponentlarni render'dan tashqarida e'lon qiling." Linter ikki joyni ko'rsatadi: qayerda ishlatilgani va qayerda yaratilgani.
Diqqat: Ichki komponentga ota komponentning o'zgaruvchisi kerak bo'lgani uchun ichkariga yozilgan bo'lishi mumkin. To'g'ri yo'l — o'sha qiymatni props bilan berish. Bu — keyingi dars.
8. Vazifalar qadami: ro'yxat komponentlari rejasi
Bu darsdan Ro'yxatlar va key darsigacha vazifalar da bitta katta ish qilamiz: vazifalar ro'yxatini React chizadi. Holat va hodisalar hozircha vanilla qoladi — React faqat <ul id="royxat"> ning ichini oladi. Hammasi bitta branch'da va besh dars oxirida bitta commit bo'ladi.
git switch -c refactor/royxat-reactBugun — reja. src/render.ts dagi vanilla funksiyalar React komponentlariga shunday mos keladi:
render.ts (v6) |
Komponent (fayl) | Qaysi darsda |
|---|---|---|
tugmaYasa() |
AmalTugmasi.tsx |
Props |
li qobig'i (ikkala qatorda) |
Qator.tsx |
children |
tahrirQatori() |
TahrirQatori.tsx |
children |
belgilanganMatn(), oddiyQator() |
BelgilanganMatn.tsx, OddiyQator.tsx |
Shartli render |
qatorYasa() |
VazifaQatori.tsx |
Shartli render |
replaceChildren(...map(qatorYasa)) |
VazifaRoyxati.tsx |
Ro'yxatlar va key |
Bugungi darsdan uchta qoida shu fayllarga to'g'ridan-to'g'ri o'tadi:
- har komponent —
src/dagi o'z.tsxfaylida, fayl nomi = komponent nomi; export function(named export), default yo'q;- nomlar o'zbekcha va ot:
VazifaQatori,AmalTugmasi.
Komponentlarning hammasi yuqori darajada yoziladi — bittasi ham boshqasining ichida emas. Fayllar src/ ning o'zida turadi, components/ papkasi yo'q. Papka tuzilmasini Kichik React loyihani tashkil qilish darsida tartiblaymiz.
9. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
ekran bo'sh, incorrect casing |
komponent nomi kichik harf bilan | WorkHours |
| komponent jim, ekranda yo'q | function da return unutilgan |
return (…) yoki .tsx (TS2786) |
does not provide an export named 'default' |
named export'ni default kabi import | import { MenuCard } |
only-export-components |
komponent faylida funksiya ham eksport | funksiyani .ts faylga |
| yozilgan matn yo'qoladi | komponent boshqa komponent ichida | yuqori darajaga chiqaring |
Cannot create components during render |
o'sha, linter topdi | o'sha |
10. Mashqlar
Mashqlar kurs/mashqlar/17/05-komponentlar/ da. 1- va 2-mashqni shu sahifadagi «Ishga tushir» bilan sinang. 3-mashq — o'z Vite loyihangizda.
1-mashq (oson): uchta xato
Sardorning kodida ekranda faqat "Ish vaqti" chiqyapti. Kodni o'zgartirmasdan, faqat o'qib, uchta xatoni toping. Keyin tuzating: ekranda sarlavha, manzil va ish vaqti chiqsin, konsol toza bo'lsin.
function siteHeader() {
return <h1>«Bahor» oshxonasi</h1>;
}
function Address() {
<p>Toshkent, Chilonzor</p>;
}
const WorkHours = () => {
return <p>Ish vaqti: 07:00–23:00</p>;
};
function App() {
return (
<div>
<siteHeader />
<Address />
<WorkHours />
</div>
);
}Konsolda:
<siteHeader /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
The tag <siteHeader> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.Ekranda:
Ish vaqti: 07:00–23:00Birinchi xato — e'londa: nomi kichik harf bilan.
Yechim
function SiteHeader() {
return <h1>«Bahor» oshxonasi</h1>;
}
function Address() {
return <p>Toshkent, Chilonzor</p>;
}
const WorkHours = () => {
return <p>Ish vaqti: 07:00–23:00</p>;
};
function App() {
return (
<div>
<SiteHeader />
<Address />
<WorkHours />
</div>
);
}Ekranda:
«Bahor» oshxonasi
Toshkent, Chilonzor
Ish vaqti: 07:00–23:00siteHeader— kichik harf: React uni HTML teg deb oldi. E'londa ham, ishlatishda hamSiteHeader.Addressdareturnyo'q — jim xato, konsolda hech narsa chiqmaydi.- Uchinchi "xato" aslida xato emas:
WorkHours— arrow funksiya,returnbilan. U to'g'ri ishlaydi. Ba'zan "xato" deb shubha qilingan joy to'g'ri bo'ladi — buni kodni ishga tushirib bilasiz.
2-mashq (o'rta): menyu sahifasini bo'laklang
Quyidagi App ni to'rtta komponentga ajrating: SiteHeader, MenuList, MenuCard (bitta taom, ichida hozircha "Osh — 35000 so'm"), SiteFooter. MenuList ichida MenuCard uch marta ishlatilsin. Ekran shunday bo'lsin:
«Bahor» menyusi
Osh — 35000 so'm
Osh — 35000 so'm
Osh — 35000 so'm
Buyurtma: +998 90 000 00 00Ishora: «Bitta katta App dan bo'laklarga» bo'limidagi kodni namuna qiling. Uch karta bir xil chiqyapti — har kartaga o'z taomini berish keyingi darsning mavzusi.
Yechim
function SiteHeader() {
return <h1>«Bahor» menyusi</h1>;
}
function MenuCard() {
return <li>Osh — 35000 so'm</li>;
}
function MenuList() {
return (
<ul>
<MenuCard />
<MenuCard />
<MenuCard />
</ul>
);
}
function SiteFooter() {
return (
<footer>
<p>Buyurtma: +998 90 000 00 00</p>
</footer>
);
}
function App() {
return (
<main>
<SiteHeader />
<MenuList />
<SiteFooter />
</main>
);
}Ekranda:
«Bahor» menyusi
Osh — 35000 so'm
Osh — 35000 so'm
Osh — 35000 so'm
Buyurtma: +998 90 000 00 00MenuCard uch marta qo'lda yozilgan, .map() bilan emas — shuning uchun key kerak emas (JSX I dagi jsxs). Daraxt: App → SiteHeader, MenuList → 3 × MenuCard, SiteFooter.
3-mashq (qiyin): fayllarga ajrating va tuzoqni tuzating
Birinchi React loyiha darsidagi bahor-menyu loyihangizda (yoki yangi npm create vite@9.2.1 … --template react-ts):
- 2-mashqdagi to'rtta komponentni
src/components/dagi to'rtta faylga chiqaring — har biri named export. App.tsxularni import qilsin, o'zi default export qolsin (main.tsxshuni kutadi).src/components/SearchBox.tsxyarating:<input aria-label="Taom qidirish" />. Sardor uniMenuListichida e'lon qilib yuborgan edi — siz uni o'z faylida yozing vaMenuListning tepasida ishlating.npx tsc -bvanpm run linttoza bo'lsin.
Yechim
// src/components/SearchBox.tsx
export function SearchBox() {
return <input aria-label="Taom qidirish" />;
}// src/components/MenuList.tsx
import { MenuCard } from "./MenuCard.tsx";
import { SearchBox } from "./SearchBox.tsx";
export function MenuList() {
return (
<section>
<SearchBox />
<ul>
<MenuCard />
<MenuCard />
<MenuCard />
</ul>
</section>
);
}// src/App.tsx
import { MenuList } from "./components/MenuList.tsx";
import { SiteFooter } from "./components/SiteFooter.tsx";
import { SiteHeader } from "./components/SiteHeader.tsx";
export default function App() {
return (
<main>
<SiteHeader />
<MenuList />
<SiteFooter />
</main>
);
}SiteHeader.tsx, MenuCard.tsx, SiteFooter.tsx — 2-mashqdagi funksiyalar, oldiga export qo'shilgan. Tekshiruv ro'yxati:
npx tsc -bjim tugaydi.TS2613chiqsa — qaysidir importda jingalak qavs unutilgan.npm run lintjim.only-export-componentschiqsa — komponent faylida boshqa narsa ham eksport qilingan.- Brauzerda qidiruv maydoniga yozing va
MenuCard.tsxdagi narxni o'zgartirib saqlang. Fast Refresh sahifani yangilaydi, lekin maydondagi matn joyida qoladi.
4-mashq: Vazifalar qadami
vazifalar da refactor/royxat-react branch'ini yarating. src/render.ts ni ochib, «Vazifalar qadami» bo'limidagi jadvalni o'zingiz tekshiring: har vanilla funksiya qaysi komponentga aylanadi? Bitta savolga yozma javob bering: nega belgilanganMatn() ham alohida komponent bo'ladi, oddiy funksiya qolmaydi?
Yechim
belgilanganMatn() vanilla'da <mark> elementlarini yasaydi — ya'ni u ekran bo'lagini qaytaradi. React'da ekran bo'lagini qaytaradigan funksiya — komponent. BelgilanganMatn JSX qaytaradi va ichida <mark> lar ro'yxati bo'ladi. Aksincha, moslar() (qidiruv.ts) faqat raqamlar (oraliqlar) qaytaradi — u oddiy funksiya bo'lib qoladi va node:test testlari o'zgarmaydi. Qoida: DOM yoki JSX qaytarsa — komponent, ma'lumot qaytarsa — oddiy funksiya.
Kod bugun o'zgarmaydi. Commit Ro'yxatlar va key darsida bo'ladi.
11. Real ishda
- Begona loyihada birinchi qaraladigan joy — komponentlar daraxti. React DevTools uni brauzerda ko'rsatadi (React DevTools).
- Kod ko'rigida (code review) ichki komponent e'loni va
returnsiz komponent — tez topiladigan xatolar. Bugun buni linter o'zi ushlaydi. - Kompaniyalarda "bir fayl — bir komponent" va named export odatda jamoa qoidasi: ESLint yoki Oxlint sozlamasida yozilgan bo'ladi.
- Intervyu savollari: "Komponent nima va oddiy funksiyadan farqi?", "Nega nom katta harf bilan?". Yana biri: "Komponentni boshqa komponent ichida e'lon qilsa nima bo'ladi?". Va: "Named yoki default export — qaysi birini tanlaysiz?".
Xulosa
- Komponent — JSX (yoki
null, matn, son) qaytaradigan funksiya; uni<Nom />bilan ishlatasiz, chaqirishni React qiladi. - Nom — PascalCase va ot: kichik harfli teg HTML teg deb olinadi, funksiya chaqirilmaydi.
returnunutilsa komponent jim yo'qoladi; TypeScript buniTS2786bilan ushlaydi.- Bir fayl — bir komponent, named export;
App— shablondagidek default. - Komponentni boshqa komponent ichida e'lon qilmang: har chizishda yangi tur — DOM va kiritilgan matn yo'qoladi.
vazifalarda ro'yxatni React'ga berish boshlandi: reja varefactor/royxat-reactbranch'i.
Keyingi dars: Props: komponentga ma'lumot uzatish — MenuCard ga taom nomi va narxini tashqaridan beramiz va vazifalar dagi birinchi ikki komponentni yozamiz.
Manbalar
- React: "Your First Component", "Importing and Exporting Components" — react.dev/learn
- React: "Nesting and organizing components", "Components and Hooks must be pure" — react.dev/learn, react.dev/reference/rules
eslint-plugin-react-hooks—static-componentsqoidasi — react.dev/reference/eslint-plugin-react-hooks- Oxlint:
react/only-export-components— oxc.rs/docs/guide/usage/linter/rules
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!