Mundarija (28)
- Bu darsda
- 1. Nega bu kerak?
- 2. JSX nimaga aylanadi
- 2.1 Bitta fayl — esbuild bilan
- 2.2 Chiqishni o'qiymiz
- 2.3 Element — oddiy obyekt
- 2.4 JSX'siz React
- 3. Qoidalar JavaScript'dan kelib chiqadi
- 3.1 Bitta ildiz
- 3.2 Har teg yopiladi
- 3.3 className va htmlFor
- 3.4 camelCase atributlar
- 3.5 style — obyekt
- 4. {} — JavaScript'ga eshik
- 4.1 Ifoda qo'yish
- 4.2 Nega {} ichida if yo'q
- 5. HTML → JSX: yig'ma jadval
- 6. Ko'p uchraydigan xatolar
- 6.1 Ko'chirilgan qatorlardagi matn yopishib qoladi
- 6.2 Komponent nomi kichik harf bilan
- 6.3 Qisqa jadval
- 7. Mashqlar
- 1-mashq (oson): HTML'ni JSX'ga o'giring
- 2-mashq (o'rta): JSX'siz yozing
- 3-mashq (qiyin): Transpiler bo'lib ko'ring
- 8. Real ishda
- Xulosa
- Manbalar
JSX I: JSX aslida JavaScript — jsx() chaqiruvi va yozish qoidalari
Qisqacha: JSX — JavaScript ichida HTML'ga o'xshatib yoziladigan sintaksis. Brauzer uni bilmaydi: transpiler har
<teg>nijsx("teg", { ...props })chaqiruviga aylantiradi, natijasi esa oddiy JavaScript obyekti — React elementi. JSX'ning hamma "g'alati" qoidasi shundan kelib chiqadi: bitta ildiz (funksiya bitta qiymat qaytaradi),classNamevahtmlFor(DOM xususiyatlari nomi), camelCase atributlar va obyekt ko'rinishidagistyle.
Bu darsda
- JSX'ga qarab, u qaysi
jsx()yokijsxs()chaqiruviga aylanishini ayta olasiz. - React elementi oddiy obyekt ekanini konsolda ko'rasiz va JSX'siz ham ekranga ro'yxat chiqarasiz.
- HTML'ni JSX'ga to'g'ri o'girasiz: yopiq teglar,
className,htmlFor, camelCase,styleobyekti. {}ichiga ifoda qo'yasiz va nega u yergaifsig'masligini tushuntirasiz.- Saytdagi, Vite'dagi va
tscdagi JSX xato xabarlarini o'qiy olasiz.
Oldin bilishingiz kerak: Birinchi React loyiha, Transpilyatsiya: Babel, SWC, esbuild va Oxc, Atributlar, xususiyatlar va dataset.
1. Nega bu kerak?
Birinchi React loyiha darsida App.tsx ni ochdingiz. Funksiya ichida return (<div>…</div>) turibdi. JavaScript fayl ichida HTML? Bu qanday ishlaydi?
Javobning yarmini 16-qismda ko'rgansiz. Transpilyatsiya darsida to'rt transpiler <li className="taom"> ni _jsxs("li", {…}) ga aylantirdi. O'shanda "React — 17-qismda, hozir faqat sintaksis muhim" degan edik. Bugun shu chaqiruvning ichiga kiramiz.
Sardor «Bahor» menyusini React'da yozyapti. Birinchi soatda uchta xatoga duch keldi:
<img src="osh.jpg">— ekranda qizil quti:Unterminated JSX contents.<label for="ism">— konsolda:Invalid DOM property 'for'.style="color: green"— butun komponent yiqildi.
Uchalasining sababi bitta: JSX — HTML emas, u JavaScript. Buni tushunsangiz, qoidalarni yodlash shart emas — ular o'z-o'zidan kelib chiqadi.
Hayotiy o'xshatish: stenografiya. Kotib qisqa belgilar bilan yozadi, keyin ularni to'liq matnga ochadi. JSX ham qisqa yozuv: <h1>Menyu</h1> aslida jsx("h1", { children: "Menyu" }). Qisqa yozuvning har qoidasi to'liq yozuvdan kelib chiqadi.
2. JSX nimaga aylanadi
2.1 Bitta fayl — esbuild bilan
JSX (JavaScript XML) — JavaScript'ning kengaytmasi: kod ichida teglar yozish imkonini beradi. Uni React jamoasi 2013-yilda o'ylab topgan. JavaScript standartida JSX yo'q — shuning uchun brauzer ham, Node ham uni to'g'ridan-to'g'ri bajara olmaydi.
Tekshirib ko'ramiz. Menu.jsx faylida bir nechta JSX bor (price va MenuCard boshqa joyda e'lon qilingan deb hisoblaymiz):
const title = <h1 className="sarlavha">Menyu</h1>;
const item = <li id="osh">Osh: {price} so'm</li>;
const label = <label htmlFor="ism">Ismingiz</label>;
const off = <button disabled>Tugadi</button>;
const card = <MenuCard name="Osh" price={price} />;
const row = <li key="osh">Osh</li>;
const list = (
<ul>
<li>Osh</li>
<li>Manti</li>
</ul>
);Uni esbuild 0.28.2 bilan o'giramiz (16-qismdagi kabi; --charset=utf8 — o'zbekcha harflar escape qilinmasin):
npx esbuild@0.28.2 Menu.jsx --jsx=automatic --charset=utf8import { jsx, jsxs } from "react/jsx-runtime";
const title = /* @__PURE__ */ jsx("h1", { className: "sarlavha", children: "Menyu" });
const item = /* @__PURE__ */ jsxs("li", { id: "osh", children: [
"Osh: ",
price,
" so'm"
] });
const label = /* @__PURE__ */ jsx("label", { htmlFor: "ism", children: "Ismingiz" });
const off = /* @__PURE__ */ jsx("button", { disabled: true, children: "Tugadi" });
const card = /* @__PURE__ */ jsx(MenuCard, { name: "Osh", price });
const row = /* @__PURE__ */ jsx("li", { children: "Osh" }, "osh");
const list = /* @__PURE__ */ jsxs("ul", { children: [
/* @__PURE__ */ jsx("li", { children: "Osh" }),
/* @__PURE__ */ jsx("li", { children: "Manti" })
] });Birinchi qator — automatic runtime ishi: transpiler jsx va jsxs funksiyalarini react/jsx-runtime modulidan o'zi import qildi. Shuning uchun faylingizda import React yozish shart emas (Transpilyatsiya darsidagi React is not defined voqeasini eslang). /* @__PURE__ */ — minifikator uchun belgi, u ham o'sha darsdan tanish.
2.2 Chiqishni o'qiymiz
Har JSX bitta funksiya chaqiruviga aylandi. Chaqiruvning qismlari:
| JSX'da | jsx() da |
Misol |
|---|---|---|
| teg nomi | 1-argument | "h1" |
| atributlar | 2-argument — obyekt | { className: "sarlavha" } |
| ichidagi narsa | o'sha obyektda children |
children: "Menyu" |
key |
3-argument (alohida) | jsx("li", {…}, "osh") |
Shu obyektni React props (properties — "xususiyatlar") deb ataydi. Props'ni Props darsida batafsil o'rganamiz, bugun bitta gap yetadi: JSX'dagi har atribut — bitta obyekt kaliti.
Endi chiqishdagi mayda detallarga qaraymiz:
- Kichik harfli teg — satr, katta harfli — o'zgaruvchi.
<h1>→"h1"(qo'shtirnoq ichida),<MenuCard>→MenuCard(qo'shtirnoqsiz, o'zgaruvchi nomi). Transpiler katta harfga qarab hal qiladi. Komponent nomlari shuning uchun katta harf bilan boshlanadi (Komponentlar darsida). price={price}→price. Kalit va qiymat nomi bir xil bo'lgani uchun esbuild obyektning qisqa yozuvini ishlatdi. Ma'nosi —price: price.- Qiymatsiz atribut —
true.<button disabled>→disabled: true. - Bir nechta bola — massiv va
jsxs.<li>ichida uch qism bor:"Osh: ",price," so'm"— ular massivga yig'ildi. Oxiridagis— "ko'plik" belgisi:jsxsReact'ga "bu massiv qo'lda yozilgan, tartibi o'zgarmaydi" deydi. Nega bu muhim — ro'yxatlar va key darsida. key— props'ga kirmaydi. U alohida, uchinchi argument bo'ldi. React uni o'zi uchun saqlaydi, komponentga bermaydi.
Maslahat: Saytimizdagi «Ishga tushir» tugmasi JSX'ni boshqa transpiler — sucrase bilan o'giradi. Uning chiqishi
_jsxruntime.jsx.call(void 0, 'h1', {…})ko'rinishida. Formati boshqa, lekin chaqirilayotgan funksiya o'sha —react/jsx-runtimedagijsx. Vite 8 da esa Oxc ishlaydi. Qaysi vosita bo'lmasin, natija bir xil.
2.3 Element — oddiy obyekt
jsx() nima qaytaradi? Konsolga chiqarib ko'ramiz:
const title = <h1 className="sarlavha">Menyu</h1>;
console.log(title);
console.log(title.type, title.props);Konsolda:
{$$typeof: Symbol(react.transitional.element), type: 'h1', key: null, props: {className: 'sarlavha', children: 'Menyu'}, _owner: null, _store: {}}
h1 {className: 'sarlavha', children: 'Menyu'}Bu — React elementi (React element): "ekranda nima bo'lishi kerak" degan tavsif. Oddiy obyekt: type — teg nomi, props — atributlar va bolalar, key — kalit.
Ikki g'alati maydon:
$$typeof— React'ning "bu haqiqatan mening elementim" belgisi. QiymatiSymbol— uni JSON'da yozib bo'lmaydi. Nega bu xavfsizlik uchun muhim — keyingi darsda._ownerva_store— development rejimidagi ichki maydonlar (ogohlantirishlar uchun). Ularga tegmaysiz.
Diqqat qiling: element — DOM tuguni emas. document.createElement("h1") haqiqiy tugun yaratadi, <h1> esa faqat uning tavsifini. O'xshatish: ofitsiant yozgan buyurtma qog'ozi — "1 osh, 2 non". Bu taomning o'zi emas, tavsifi. Oshpaz qog'ozni o'qib, haqiqiy taomni tayyorlaydi. React'da oshpaz — React DOM: u elementlarni o'qib, haqiqiy DOM tugunlarini yaratadi.
flowchart LR
A["JSX yozuvi"] -->|"transpiler"| B["jsx() chaqiruvi"]
B -->|"bajariladi"| C["React elementi<br/>(oddiy obyekt)"]
C -->|"React DOM"| D["DOM tugunlari"]Rasmda chapdan o'ngga qarang: birinchi o'q build paytida (Vite yoki saytdagi sucrase), qolganlari brauzerda bajariladi.
2.4 JSX'siz React
Agar JSX faqat qisqa yozuv bo'lsa, usiz ham ishlash kerak. Sinab ko'ramiz — jsx va jsxs ni o'zimiz import qilamiz:
import { jsx, jsxs } from "react/jsx-runtime";
function App() {
return jsxs("ul", {
children: [
jsx("li", { children: "Osh — 35000 so'm" }),
jsx("li", { children: "Manti — 30000 so'm" }),
],
});
}Ekranda:
Osh — 35000 so'm
Manti — 30000 so'mIshladi — bitta ham teg yozmadik. Real kodda bunday hech kim yozmaydi: react/jsx-runtime — transpiler uchun mo'ljallangan modul. Biz uni faqat isbot uchun chaqirdik: JSX — sintaksis, React'ning o'zi esa oddiy funksiyalar va obyektlar.
Maslahat: Eski kodda
React.createElement("li", null, "Osh")ni ko'rasiz — bu classic runtime (Transpilyatsiya darsida). Farqi: bolalarchildrenkaliti emas, qo'shimcha argumentlar bo'lib beriladi. Ma'nosi bir xil. React 19 dacreateElementhali bor, lekin JSX endijsx()ga o'giriladi.
Tekshirib ko'ring:
<Menu />va<menu />nimaga o'giriladi?
Javob
<Menu /> → jsx(Menu, {}) — Menu degan o'zgaruvchi (komponent). <menu /> → jsx("menu", {}) — satr, ya'ni HTML'dagi <menu> tegi. Transpiler faqat birinchi harfga qaraydi: katta harf — o'zgaruvchi, kichik harf — HTML teg.
3. Qoidalar JavaScript'dan kelib chiqadi
Endi Sardorning xatolariga qaytamiz. Har biri "JSX = jsx() chaqiruvi" degan bitta g'oyadan tushuntiriladi.
3.1 Bitta ildiz
Sardor sarlavha va matnni yonma-yon qaytarmoqchi bo'ldi:
function App() {
return (
<h1>Salom</h1>
<p>Menyu</p>
);
}Saytda qizil quti:
JSX sintaksis xatosi (4-qator, 16-ustun): Unterminated regular expression"Yopilmagan regular expression"? Qayerda regex bor? Buni JavaScript tahlilchisi (parser) kabi o'qib ko'ramiz. <h1>Salom</h1> — tugagan ifoda. Uning ortidan < keldi. Ifodadan keyingi < — JavaScript'da "kichik" operatori. Keyin p>Menyu<, so'ng /p> — / belgisi bilan regex boshlanadi, lekin yopuvchi / yo'q. Xabar g'alati, lekin mantiqli: tahlilchi JavaScript qoidasi bilan o'qiyapti. Qoida: xabar tushunarsiz bo'lsa, ko'rsatilgan joydan oldingi qatorni tekshiring.
Vite 8 (ichida Oxc) shu xatoni aniqroq aytadi:
Adjacent JSX elements must be wrapped in an enclosing tag.
Did you want a JSX fragment `<>...</>`?"Yonma-yon JSX elementlari bitta o'rab turuvchi tegga olinishi kerak. JSX fragment <>...</> ni nazarda tutdingizmi?" Xuddi shu kod .tsx faylda bo'lsa, tsc ham to'xtaydi:
TS2657: JSX expressions must have one parent element."JSX ifodalarining bitta ota elementi bo'lishi shart." Nega? O'girilgan holatini tasavvur qiling: return jsx("h1", …) jsx("p", …);. Funksiya ikkita qiymat qaytara olmaydi — bu JavaScript qoidasi.
Tuzatish — ikkalasini bitta tegga o'rash:
function App() {
return (
<div>
<h1>Salom</h1>
<p>Menyu</p>
</div>
);
}Ekranda:
Salom
MenyuOrtiqcha <div> kerak bo'lmasa — <>…</> (Fragment) bor. U DOM'ga hech narsa qo'shmaydi; keyingi darsda to'liq ko'ramiz.
return dan keyingi qavslarga ham e'tibor bering. Ular JSX qoidasi emas — JavaScript'ning nuqta-vergulni avtomatik qo'yish (ASI) qoidasi uchun. Qavssiz return dan keyin yangi qatorga o'tsangiz, JavaScript return; deb o'qiydi va funksiya undefined qaytaradi:
function App() {
return
<h1>Menyu</h1>;
}Ekran bo'sh qoladi, xato ham yo'q — eng yoqimsiz turdagi xato. Ko'p qatorli JSX'ni har doim return ( bilan boshlang.
3.2 Har teg yopiladi
HTML'da <img>, <br>, <input> yopilmaydi — ular bo'sh elementlar (void elements). JSX'da bunday istisno yo'q: har teg yopilishi shart. Aks holda tahlilchi tegning ichidagi narsani oxirigacha qidiradi:
function App() {
return <img src="osh.jpg" alt="Osh">;
}Saytda:
JSX sintaksis xatosi (2-qator, 40-ustun): Unterminated JSX contents"Tugallanmagan JSX tarkibi" — tahlilchi <img> ning yopuvchi tegini fayl oxirigacha qidirdi va topmadi. .tsx faylda tsc bu safar uchta xato beradi:
TS17008: JSX element 'img' has no corresponding closing tag.
TS1381: Unexpected token. Did you mean `{'}'}` or `}`?
TS1005: '</' expected.Birinchisi — haqiqiy sabab: "img elementining yopuvchi tegi yo'q". Qolgan ikkitasi — oqibat: tahlilchi ; va } ni <img> ichidagi matn deb o'yladi. Qoida: bir nechta xato chiqsa, birinchisini tuzating — qolganlari ko'pincha o'zi yo'qoladi.
Tuzatish — o'zini yopuvchi teg (self-closing): <img src="osh.jpg" alt="Osh" />, <br />, <input />. Istalgan teg shunday yopilishi mumkin: ichi bo'sh <div></div> o'rniga <div />.
3.3 className va htmlFor
Sardorning ikkinchi xatosi:
function App() {
return (
<div class="karta">
<label for="ism">Ism</label>
<input id="ism" />
</div>
);
}Konsolda:
Invalid DOM property `for`. Did you mean `htmlFor`?
Invalid DOM property `class`. Did you mean `className`?Ekranda:
Ism"Noto'g'ri DOM xususiyati for. htmlFor ni nazarda tutdingizmi?" Komponent chizildi, lekin React ogohlantirdi. (Konsoldagi xabarlar React'ning development rejimida chiqadi. Saytdagi «Ishga tushir» aynan shu rejimda ishlaydi.)
Nega className? JSX atributlari — props obyektining kalitlari. React DOM ularni HTML atribut nomi bilan emas, DOM xususiyati nomi bilan qabul qiladi. Atributlar va xususiyatlar darsidagi jadvalni eslang: class atributining xususiyati — el.className, for ning xususiyati — label.htmlFor. DOM API bu nomlarni tanlagan, chunki class va for JavaScript'ning kalit so'zlari. React o'sha nomlarga ergashdi. Vanilla kodda li.className = "taom" deb yozganingizni eslang — JSX'dagi className o'sha.
TypeScript bu yerda qattiqroq: ogohlantirish emas, xato.
export function App() {
return (
<div class="karta">
<label for="ism">Ism</label>
<input id="ism" />
</div>
);
}Xato:
TS2322: Type '{ class: string; children: Element[]; }' is not assignable to type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.
Property 'class' does not exist on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'. Did you mean 'className'?
TS2322: Type '{ for: string; children: string; }' is not assignable to type 'DetailedHTMLProps<LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>'.
Property 'for' does not exist on type 'DetailedHTMLProps<LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>'. Did you mean 'htmlFor'?Uzun, lekin o'qisa bo'ladi. { class: string; children: Element[]; } — TypeScript JSX atributlaridan yasagan props obyekti (yana isbot: atributlar — obyekt). DetailedHTMLProps<…> — <div> qabul qiladigan props turi, @types/react paketidan. Eng muhim qism — oxiri: Did you mean 'className'?.
3.4 camelCase atributlar
Xuddi shu qoida boshqa atributlarga ham tegishli: nom DOM xususiyatidan olinadi, ko'p so'zli nom esa camelCase (har keyingi so'z katta harf bilan) bo'ladi.
| HTML | JSX |
|---|---|
tabindex |
tabIndex |
maxlength, readonly |
maxLength, readOnly |
onclick, oninput |
onClick, onInput |
stroke-width (SVG) |
strokeWidth |
aria-label, data-id |
o'zgarmaydi |
Oxirgi qator — istisno: aria-* va data-* atributlari HTML'dagidek, chiziqcha bilan yoziladi.
Kichik harf bilan yozsangiz:
function App() {
return (
<div tabindex="0">
<svg><circle r="5" stroke-width="2" /></svg>
Osh
</div>
);
}Konsolda:
Invalid DOM property `stroke-width`. Did you mean `strokeWidth`?
Invalid DOM property `tabindex`. Did you mean `tabIndex`?Ekranda:
OshHodisa atributlarida (onclick) xavf kattaroq: React kichik harfli onclick ni ishlovchi deb tanimaydi va bosilganda funksiya chaqirilmaydi. Hodisalarni Hodisalarni boshqarish darsida o'rganamiz; bugun faqat nomi. TypeScript buni ham ushlaydi:
export function App() {
return <button onclick={() => {}}>Buyurtma</button>;
}Xato:
TS2322: Type '{ onclick: () => void; children: string; }' is not assignable to type 'DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>'.
Property 'onclick' does not exist on type 'DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>'. Did you mean 'onClick'?3.5 style — obyekt
Sardorning uchinchi xatosi eng og'iri edi:
function App() {
return <p style="color: green">Tayyor</p>;
}Konsolda:
Uncaught Error: The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX."style props'i satr emas, stil xususiyatlaridan qiymatlarga xaritalash (obyekt) kutadi. Masalan: style={{marginRight: spacing + 'em'}}." Bu ogohlantirish emas — xato: komponent chizilmaydi, saytda «Komponentni chizishda xato» qutisi chiqadi.
To'g'risi — style={{ … }}. Ikki juft jingalak qavs boshida qo'rqitadi, lekin ularning vazifasi har xil: tashqi {} — "bu yerda JavaScript ifodasi" (pastda ko'ramiz), ichki {} — oddiy obyekt literali. Obyektni oldin o'zgaruvchiga olsangiz, ikkalasi ajralib ko'rinadi.
React DOM bu obyektdan qanday HTML yasashini ko'raylik:
import { flushSync } from "react-dom";
import { createRoot } from "react-dom/client";
const root = createRoot(document.getElementById("root"));
const box = { color: "green", fontSize: 18, padding: 8 };
flushSync(() => {
root.render(
<label htmlFor="ism" className="yorliq" style={box}>
Ism
</label>
);
});
console.log(document.getElementById("root").innerHTML);Konsolda:
<label for="ism" class="yorliq" style="color: green; font-size: 18px; padding: 8px;">Ism</label>Ekranda:
IsmflushSync — React'ga "hozir, shu zahoti chizib bo'l" degan buyruq. Usiz root.render ishni keyinroqqa qoldiradi va keyingi qatordagi innerHTML hali bo'sh bo'ladi. Uni bu yerda faqat natijani ko'rish uchun ishlatdik — oddiy kodda kerak bo'lmaydi.
Natijada uchta o'girish ko'rinyapti:
className→class,htmlFor→for: DOM'da yana oddiy HTML atributlari.fontSize→font-size: kalitlar camelCase, xuddi stillarni JS'dan boshqarish darsidagiel.style.fontSizekabi.18→18px: son yozsangiz, Reactpxqo'shadi. Birliksiz xususiyatlar (lineHeight,opacity,zIndex,flexGrow) bundan mustasno — ular son bo'lib qoladi. Boshqa birlik kerak bo'lsa — satr:width: "50%",padding: "1rem".
TypeScript satrni darhol rad etadi:
export function App() {
return <p style="color: green">Tayyor</p>;
}Xato:
TS2559: Type 'string' has no properties in common with type 'Properties<string | number, string & {}>'."string turining Properties<…> turi bilan umumiy xususiyati yo'q." Properties — CSS xususiyatlari obyekti turi (csstype paketidan, @types/react uni ishlatadi).
Maslahat: Amalda
stylekam ishlatiladi. Asosiy bezak — CSS fayl vaclassName.style— hisoblanadigan qiymatlar uchun: progress chizig'ining kengligi, foydalanuvchi tanlagan rang. Uslub berish usullarini React'da stil berish darsida taqqoslaymiz.
Tekshirib ko'ring:
style={{ marginTop: 10, lineHeight: 1.5 }}DOM'da qanday yoziladi?
Javob
style="margin-top: 10px; line-height: 1.5;". marginTop → margin-top (camelCase chiziqchaga qaytadi), 10 → 10px. lineHeight esa birliksiz xususiyat: 1.5 "shrift o'lchamining 1.5 baravari" degani, unga px qo'shilmaydi.
4. {} — JavaScript'ga eshik
4.1 Ifoda qo'yish
Shu paytgacha atribut qiymatlari qo'shtirnoqda edi — oddiy satr. Qiymat hisoblanishi kerak bo'lsa, jingalak qavs ishlatiladi. {} ichidagi kod JavaScript sifatida bajariladi:
function App() {
const price = 35000;
const isOpen = true;
return (
<div>
<p>Narx: {price} so'm</p>
<p>Ikki porsiya: {price * 2} so'm</p>
<p>Holat: {isOpen ? "ochiq" : "yopiq"}</p>
<p title={`Narx: ${price}`}>{"osh".toUpperCase()}</p>
</div>
);
}Ekranda:
Narx: 35000 so'm
Ikki porsiya: 70000 so'm
Holat: ochiq
OSH{} ikki joyda ishlaydi:
- bola o'rnida —
<p>{price}</p>: qiymatchildrenga tushadi; - atribut qiymati o'rnida —
title={…}: qiymat props kalitiga tushadi.
Teg nomi o'rnida ishlamaydi: <{tag}> yozib bo'lmaydi.
Qo'shtirnoq va jingalak qavsni aralashtirmang. title="{price}" — oddiy satr, ichida jingalak qavslar bilan. esbuild chiqishida farq aniq ko'rinadi:
const d = /* @__PURE__ */ jsxs("p", { title: "{price}", children: [
price,
" so'm"
] });Bu <p title="{price}">{price} so'm</p> ning o'girilgani. Atributda "{price}" satr bo'lib qoldi, bola o'rnidagi {price} esa o'zgaruvchi bo'ldi.
4.2 Nega {} ichida if yo'q
{} ichiga faqat ifoda (expression) yoziladi — qiymat beradigan kod: o'zgaruvchi, price * 2, funksiya chaqiruvi, ternary. if, for, const — ko'rsatmalar (statement): ular qiymat bermaydi.
function App() {
const ok = true;
return <p>{if (ok) { "ha" }}</p>;
}Saytda:
JSX sintaksis xatosi (3-qator, 15-ustun): Unexpected tokenO'girilgan holatini tasavvur qiling: jsx("p", { children: if (ok) … }). Obyekt kalitining qiymati o'rnida if turibdi — JavaScript bunga ruxsat bermaydi, xuddi const a = if (ok) … kabi. JSX qoidasi yana JavaScript qoidasidan chiqdi.
Ikki yo'l bor: ifoda variantini ishlatish ({ok ? "ha" : "yo'q"}) yoki if ni return dan oldin yozish:
function App() {
const ok = true;
let answer = "yo'q";
if (ok) {
answer = "ha";
}
return <p>Javob: {answer}</p>;
}Ekranda:
Javob: haShartga qarab UI tanlashning hamma usullari — Shartli render darsida. {} ichiga qanday qiymat qo'ysangiz ekranda nima chiqishi — keyingi darsda.
Tekshirib ko'ring: HTML'dagi
<label for="tel">Telefon</label>ni JSX'ga o'giring:<label[:htmlFor]="tel">Telefon</label>.<input maxlength="9">esa:<input[:maxLength]="9" />.
Javob
htmlFor va maxLength. Ikkalasi ham DOM xususiyati nomi: label.htmlFor, input.maxLength. Ikkinchisida tegni /> bilan yopishni unutmang.
5. HTML → JSX: yig'ma jadval
| HTML | JSX | Sabab |
|---|---|---|
<img src="a.jpg"> |
<img src="a.jpg" /> |
har teg yopiladi |
class="karta" |
className="karta" |
DOM xususiyati nomi |
for="ism" |
htmlFor="ism" |
DOM xususiyati nomi |
tabindex="0" |
tabIndex={0} |
camelCase |
style="color: red" |
style={{ color: "red" }} |
style — obyekt |
<!-- izoh --> |
{/* izoh */} |
keyingi darsda |
| ikki ildiz yonma-yon | <div> yoki <> ichida |
funksiya bitta qiymat qaytaradi |
tabIndex={0} ga e'tibor bering: "0" satr ham ishlaydi, lekin son {} bilan yoziladi. Qoida: satr — qo'shtirnoqda, boshqa hamma narsa (son, boolean, o'zgaruvchi, obyekt, funksiya) — {} da.
6. Ko'p uchraydigan xatolar
6.1 Ko'chirilgan qatorlardagi matn yopishib qoladi
function App() {
return (
<p>
Narxi:
<b>35000</b>
so'm
</p>
);
}Ekranda:
Narxi:35000so'mBo'shliqlar qayerga ketdi? JSX'ning qoidasi: qator ko'chishi bor bo'shliq butunlay olib tashlanadi. esbuild chiqishida ko'rinadi — children: ["Narxi:", jsx("b", …), "so'm"], bo'sh joy yo'q. Bu HTML'dan farq qiladi: HTML'da qator ko'chishi bitta bo'shliqqa aylanadi.
Tuzatish — so'zlarni bitta qatorda yozing (Narxi: <b>35000</b> so'm) yoki bo'shliqni ifoda sifatida qo'ying: {" "}.
function App() {
return (
<p>
Narxi: <b>35000</b> so'm
</p>
);
}Ekranda:
Narxi: 35000 so'm6.2 Komponent nomi kichik harf bilan
function menuCard() {
return <p>Osh</p>;
}
function App() {
return <menuCard />;
}Konsolda:
<menuCard /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
The tag <menuCard> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.Ekran bo'sh: <menuCard /> → jsx("menuCard", {}) — satr, ya'ni React menucard degan noma'lum HTML teg yaratdi. Funksiya umuman chaqirilmadi. Xabar: "Komponent nomi katta harf bilan (PascalCase) bo'lsin". Nom MenuCard bo'lsa, hammasi joyida.
6.3 Qisqa jadval
| Belgi | Sabab | Davosi |
|---|---|---|
Unterminated regular expression |
yonma-yon ikki ildiz | <div> yoki <> bilan o'rang |
Unterminated JSX contents |
<img>, <br> yopilmagan |
<img /> |
Invalid DOM property 'class' |
HTML nomi | className, htmlFor |
style prop expects a mapping |
style satr |
style={{ … }} |
| ekran bo'sh, xato yo'q | return dan keyin qator ko'chdi |
return ( |
Unexpected token {} ichida |
if/for ko'rsatma |
ternary yoki return dan oldin |
7. Mashqlar
Mashqlar kurs/mashqlar/17/03-jsx/ da. Yechimni «Ishga tushir» bilan sinang yoki o'z React loyihangizdagi App o'rniga qo'yib ko'ring.
1-mashq (oson): HTML'ni JSX'ga o'giring
«Bahor» saytidagi buyurtma kartasining HTML'i bor. Uni App komponentiga JSX qilib ko'chiring. Ekran va konsol toza bo'lsin (ogohlantirishsiz).
<div class="karta" tabindex="0">
<img src="osh.jpg" alt="Osh">
<label for="soni">Soni:</label>
<input id="soni" type="number" value="1" readonly>
<p style="color: green; font-weight: bold">Tayyor</p>
<br>
</div>Ishora: jadvaldagi har qatorni tekshiring — yopilmagan teglar ikkita emas, uchta. style dagi font-weight qanday yoziladi?
Yechim
function App() {
return (
<div className="karta" tabIndex={0}>
<img src="osh.jpg" alt="Osh" />
<label htmlFor="soni">Soni:</label>
<input id="soni" type="number" value="1" readOnly />
<p style={{ color: "green", fontWeight: "bold" }}>Tayyor</p>
<br />
</div>
);
}Ekranda:
Soni:
TayyorYopilmagan teglar — <img>, <input>, <br>. readonly → readOnly va qiymatsiz qoldi (true). font-weight → fontWeight. readOnly ni unutsangiz, React boshqa ogohlantirish beradi: value bor, lekin o'zgartirish yo'li yo'q. Bu mavzu — Formalar darsida.
2-mashq (o'rta): JSX'siz yozing
Quyidagi komponentni JSX ishlatmasdan, react/jsx-runtime dagi jsx va jsxs bilan qayta yozing. Ekrandagi natija bir xil bo'lsin.
function App() {
return (
<section className="menyu">
<h2>Bugungi taomlar</h2>
<p>Osh — <b>35000</b> so'm</p>
</section>
);
}Ekranda:
Bugungi taomlar
Osh — 35000 so'mIshora: «Chiqishni o'qiymiz» bo'limidagi qoidalar — bitta bola → jsx va children da qiymat; bir nechta bola → jsxs va massiv. <p> ichida nechta bola bor? Matnlardagi bo'shliqlarni yo'qotmang.
Yechim
import { jsx, jsxs } from "react/jsx-runtime";
function App() {
return jsxs("section", {
className: "menyu",
children: [
jsx("h2", { children: "Bugungi taomlar" }),
jsxs("p", {
children: [
"Osh — ",
jsx("b", { children: "35000" }),
" so'm",
],
}),
],
});
}Ekranda:
Bugungi taomlar
Osh — 35000 so'm<section> ning ikkita bolasi bor (h2 va p) — jsxs. <p> ning uchta: "Osh — ", <b> elementi va " so'm" — yana jsxs. <h2> va <b> ning bittadan bolasi bor — jsx. Bo'shliqlar satrlarning ichida: "Osh — " oxirida, " so'm" boshida. JSX bitta qatorda yozilgani uchun ular saqlangan edi.
3-mashq (qiyin): Transpiler bo'lib ko'ring
Quyidagi JSX esbuild'dan qanday chiqishini qog'ozda yozing. Keyin Row.jsx fayliga saqlab, npx esbuild@0.28.2 Row.jsx --jsx=automatic --charset=utf8 bilan solishtiring.
const row = (
<li key={dish.id} className={dish.hot ? "issiq" : ""}>
<DishName text={dish.name} />
{dish.price} so'm
</li>
);Uchta savolga ham javob bering: (1) jsx mi yoki jsxs? (2) key qayerga tushadi? (3) DishName qo'shtirnoqdami?
Yechim
import { jsx, jsxs } from "react/jsx-runtime";
const row = /* @__PURE__ */ jsxs("li", { className: dish.hot ? "issiq" : "", children: [
/* @__PURE__ */ jsx(DishName, { text: dish.name }),
dish.price,
" so'm"
] }, dish.id);<li>ning uchta bolasi bor (DishNameelementi,dish.price," so'm") —jsxs.DishNamening bolasi yo'q —jsx.key— props'da emas, oxirgi argumentda:}, dish.id).- Yo'q:
DishNamekatta harf bilan — o'zgaruvchi."li"esa satr.
Yana ikki detal: ternary {} dan olinib, to'g'ridan-to'g'ri className qiymatiga qo'yildi. {dish.price} va so'm orasidagi bo'shliq satrning boshida saqlandi (" so'm") — ular bitta qatorda edi. Qator ko'chishi esa izsiz yo'qoldi.
8. Real ishda
- HTML maketni JSX'ga o'girish — frontend dasturchining kundalik ishi. Dizayner yoki eski sahifadan kelgan HTML'da
class,for,style="…"va yopilmagan teglar albatta bo'ladi. TypeScript (.tsx) ularning hammasini build'dan oldin ushlaydi —vazifalardatsc -baynan shuning uchun. - JSX faqat React'niki emas. Preact ham JSX ishlatadi — faqat
jsx()boshqa paketdan keladi (tsconfig'dagijsxImportSourcesozlamasi). G'oya o'sha: JSX — funksiya chaqiruvining qisqa yozuvi. - Intervyu savollari: "JSX nima va brauzer uni qanday tushunadi?", "Nega
classemas,className?", "React.createElementvajsx()farqi?", "Nega komponent bitta ildiz qaytaradi?", "React elementi va DOM tuguni farqi?".
Xulosa
- JSX — sintaksis: transpiler uni
jsx("teg", props, key)yokijsxs(…)chaqiruviga aylantiradi, import'ni automatic runtime o'zi qo'shadi. jsx()natijasi — React elementi:type,props,keyli oddiy obyekt. DOM tugunini React DOM yaratadi.- Bitta ildiz — funksiya bitta qiymat qaytaradi; har teg yopiladi; ko'p qatorli JSX —
return (bilan. - Atributlar — props kalitlari:
className,htmlFor, camelCase (tabIndex,onClick);aria-*,data-*o'zgarmaydi. style— obyekt:style={{ fontSize: 18 }}→font-size: 18px.{}ichida faqat ifoda: o'zgaruvchi, hisob, chaqiruv, ternary —ifemas.
Keyingi dars: JSX II: ifodalar, Fragment va nima ekranga chiqadi — {} ichiga son, massiv, null yoki obyekt qo'ysak nima bo'ladi, 0 && tuzog'i va JSX nega XSS'dan himoya qiladi.
Manbalar
- React: "Writing Markup with JSX", "JavaScript in JSX with Curly Braces" — react.dev/learn
- React: "Common components (e.g.
<div>)" —className,htmlFor,style— react.dev/reference/react-dom/components/common - React blog: "Introducing the New JSX Transform" (2020-09-22) — legacy.reactjs.org/blog
- esbuild: "JSX" (
--jsx=automatic) — esbuild.github.io/api
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!