4-bo‘lim
Komponentlar va props
Komponent yozish qoidalari, props va yoyish, odatiy qiymatlar, children, props ning o'zgarmasligi va bir tomonlama ma'lumot oqimi.
Ushbu bo‘lim mundarijasi
Komponent - katta harf bilan boshlanadigan funksiya. U props
obyektini oladi va JSX qaytaradi.
Eng oddiy komponent #
import { renderToStaticMarkup } from "react-dom/server";
function Salom() {
return <h1>Salom, dunyo!</h1>;
}
const Qisqa = () => <p>O'q funksiya ham bo'ladi</p>;
console.log(renderToStaticMarkup(<Salom />));
console.log(renderToStaticMarkup(<Qisqa />));
<h1>Salom, dunyo!</h1>
<p>O'q funksiya ham bo'ladi</p>
Bu qoida emas, balki sintaksis:
<salom /> // HTML tegi deb o'ylaydi
<Salom /> // komponent deb biladi
JSX kichik harfli nomni HTML elementi deb hisoblaydi va uni
"salom" satri sifatida uzatadi. Brauzer esa bunday tegni
bilmaydi va hech narsa chizilmaydi.
Xato xabari ham chiqmaydi - shunchaki bo'sh joy qoladi. Shuning uchun "komponentim ko'rinmayapti" muammosining birinchi sababi odatda shu.
Qoida: komponent nomi doim PascalCase.
Props #
import { renderToStaticMarkup } from "react-dom/server";
import { chiroyli } from "./dom-muhit.mjs";
function Kartochka(props) {
return (
<div>
<h3>{props.ism}</h3>
<p>{props.ball} ball</p>
</div>
);
}
function Yoyilgan({ ism, ball }) {
return (
<div>
<h3>{ism}</h3>
<p>{ball} ball</p>
</div>
);
}
console.log(chiroyli(renderToStaticMarkup(
<Kartochka ism="Malika" ball={88} />)));
console.log("---");
console.log(chiroyli(renderToStaticMarkup(
<Yoyilgan ism="Nodira" ball={91} />)));
<div>
<h3>Malika</h3>
<p>88 ball</p>
</div>
---
<div>
<h3>Nodira</h3>
<p>91 ball</p>
</div>
Ikkala shakl bir xil. Yoyish (destructuring) qulayroq: komponent boshida qaysi props kutilayotgani darhol ko'rinadi.
Amalda deyarli har doim ikkinchi shakl ishlatiladi.
Qiymat turlari #
import { renderToStaticMarkup } from "react-dom/server";
import { chiroyli } from "./dom-muhit.mjs";
function Korish({ matn, son, mantiqiy, royxat, obyekt, vazifa }) {
return (
<ul>
<li>{typeof matn}</li>
<li>{typeof son}</li>
<li>{typeof mantiqiy}</li>
<li>{Array.isArray(royxat) ? "massiv" : "?"}</li>
<li>{obyekt.guruh}</li>
<li>{typeof vazifa}</li>
</ul>
);
}
console.log(chiroyli(renderToStaticMarkup(
<Korish
matn="salom"
son={42}
mantiqiy
royxat={[1, 2]}
obyekt={{ guruh: "A1" }}
vazifa={() => {}}
/>,
)));
<ul>
<li>string</li>
<li>number</li>
<li>boolean</li>
<li>massiv</li>
<li>A1</li>
<li>function</li>
</ul>
Satrdan boshqa hamma narsa jingalak qavs ichida beriladi:
| Yozuv | Natija |
|---|---|
matn="salom" | Satr |
son={42} | Son |
mantiqiy | true (qisqa shakl) |
royxat={[1, 2]} | Massiv |
vazifa={f} | Funksiya |
Odatiy qiymatlar #
import { renderToStaticMarkup } from "react-dom/server";
function Tugma({ matn = "Yuborish", turi = "asosiy", ochiq = true }) {
return (
<button className={turi} disabled={!ochiq}>
{matn}
</button>
);
}
console.log(renderToStaticMarkup(<Tugma />));
console.log(renderToStaticMarkup(<Tugma matn="Bekor" turi="ikkilamchi" />));
console.log(renderToStaticMarkup(<Tugma ochiq={false} />));
<button class="asosiy">Yuborish</button>
<button class="ikkilamchi">Bekor</button>
<button class="asosiy" disabled="">Yuborish</button>
Odatiy qiymat oddiy JavaScript sintaksisi bilan beriladi - React ning maxsus imkoniyati emas.
Eski kodda shunday yozilardi:
Tugma.defaultProps = { matn: "Yuborish" };
React 19 da funksiya komponentlari uchun defaultProps
butunlay olib tashlandi - u endi ishlamaydi va ogohlantirish
ham bermaydi.
Yuqoridagi shakl - funksiya parametrining odatiy qiymati - yagona to'g'ri yo'l. U soddaroq va JavaScript ning o'z imkoniyati.
children #
import { renderToStaticMarkup } from "react-dom/server";
import { chiroyli } from "./dom-muhit.mjs";
function Panel({ sarlavha, children }) {
return (
<section>
<h3>{sarlavha}</h3>
<div className="tana">{children}</div>
</section>
);
}
const element = (
<Panel sarlavha="Talabalar">
<p>Birinchi qator</p>
<p>Ikkinchi qator</p>
</Panel>
);
console.log(chiroyli(renderToStaticMarkup(element)));
<section>
<h3>Talabalar</h3>
<div class="tana">
<p>Birinchi qator</p>
<p>Ikkinchi qator</p>
</div>
</section>
children - maxsus prop. Unga komponentning ochilish va
yopilish tegi orasidagi hamma narsa tushadi.
Bu React dagi eng kuchli naqshlardan biri: Panel ichida nima
bo'lishini bilmaydi, lekin uni chiroyli o'rab beradi.
Panel ni ikki xil yozish mumkin edi:
<Panel sarlavha="X" matn="..." royxat={[...]} tugmalar={[...]} />
<Panel sarlavha="X">{/* istalgan narsa */}</Panel>
Birinchisi har bir yangi ehtiyoj uchun yangi prop talab qiladi va komponent asta-sekin o'nlab props bilan shishib ketadi.
Ikkinchisi esa o'zgarmaydi: ichiga nima qo'ysangiz, o'sha chiziladi.
Qoida: komponentga nima chizishni aytish o'rniga, qayerga chizishni ayting.
Bir nechta "teshik" #
import { renderToStaticMarkup } from "react-dom/server";
import { chiroyli } from "./dom-muhit.mjs";
function Sahifa({ boshi, yoni, children }) {
return (
<div className="sahifa">
<header>{boshi}</header>
<aside>{yoni}</aside>
<main>{children}</main>
</div>
);
}
const element = (
<Sahifa boshi={<h1>Kutubxona</h1>} yoni={<nav>Menyu</nav>}>
<p>Asosiy mazmun</p>
</Sahifa>
);
console.log(chiroyli(renderToStaticMarkup(element)));
<div class="sahifa">
<header>
<h1>Kutubxona</h1>
</header>
<aside>
<nav>Menyu</nav>
</aside>
<main>
<p>Asosiy mazmun</p>
</main>
</div>
Props ga JSX ning o'zini berish mumkin. Shunda bitta komponentda bir nechta "teshik" bo'ladi.
Props o'zgarmas #
import { renderToStaticMarkup } from "react-dom/server";
function Yomon({ ball }) {
try {
const props = { ball };
Object.freeze(props);
props.ball = 100;
return <p>Ball: {props.ball}</p>;
} catch (xato) {
return <p>Xato: {xato.constructor.name}</p>;
}
}
function Yaxshi({ ball }) {
const oshirilgan = ball + 5;
return <p>Yangi ball: {oshirilgan}</p>;
}
console.log(renderToStaticMarkup(<Yomon ball={88} />));
console.log(renderToStaticMarkup(<Yaxshi ball={88} />));
<p>Xato: TypeError</p>
<p>Yangi ball: 93</p>
Komponent o'ziga kelgan props ni o'zgartirmasligi kerak.
Yuqoridagi Yomon da obyekt ataylab muzlatilgan va unga yozishga
urinish TypeError tashladi - modullar har doim qat'iy rejimda
ishlaydi.
Lekin asosiy muammo boshqa. Props muzlatilmagan bo'lsa ham, uni o'zgartirish foydasiz: React o'zgarishni sezmaydi va ekranni yangilamaydi.
Buning sababi React ning asosiy qoidasi - bir tomonlama oqim: ma'lumot yuqoridan pastga, ota-komponentdan bolaga tushadi.
Bola ma'lumotni o'zgartirishi kerak bo'lsa, u otaga xabar beradi - odatda prop sifatida berilgan funksiya orqali. Otasi esa o'z holatini o'zgartiradi va yangi qiymatni pastga uzatadi.
Buni 7-bo'limda holat bilan birga ko'ramiz.
Yangi qiymat kerak bo'lsa, Yaxshi dagi kabi yangi
o'zgaruvchi yarating.
Props ni yoyib berish #
import { renderToStaticMarkup } from "react-dom/server";
function Kirish({ nom, turi, ...qolgani }) {
return <input name={nom} type={turi} {...qolgani} />;
}
const sozlama = { nom: "email", turi: "email" };
console.log(renderToStaticMarkup(
<Kirish {...sozlama} placeholder="[email protected]" />));
console.log(renderToStaticMarkup(
<Kirish nom="yosh" turi="number" min={0} max={120} />));
<input type="email" placeholder="[email protected]" name="email"/>
<input type="number" min="0" max="120" name="yosh"/>
{...obyekt} - obyektning hamma xossasini props sifatida
uzatadi.
...qolgani esa qolgan hamma props ni yig'ib oladi va ularni
ichki elementga o'tkazadi.
{...props} qulay, lekin u nima uzatilayotganini yashiradi.
Komponentga qarab, u qanday props qabul qilishini bilib
bo'lmaydi.
Bundan tashqari, keraksiz props DOM ga tushib qolishi mumkin va brauzer konsolida ogohlantirish chiqadi.
Foydali holat: yuqoridagi Kirish kabi o'rovchi komponentlar,
ular standart elementga qo'shimcha props o'tkazishi kerak
bo'lganda.
Qolgan joyda props ni ochiq yozgan ma'qul.
Komponentni bo'lish #
import { renderToStaticMarkup } from "react-dom/server";
import { chiroyli } from "./dom-muhit.mjs";
function Nishon({ holat }) {
const matn = holat === "faol" ? "Faol" : "Nofaol";
return <b>{matn}</b>;
}
function Qator({ talaba }) {
return (
<li>
{talaba.ism} - <Nishon holat={talaba.holat} />
</li>
);
}
function Royxat({ talabalar }) {
return <ul>{talabalar.map((t) => <Qator key={t.ism} talaba={t} />)}</ul>;
}
const talabalar = [
{ ism: "Malika", holat: "faol" },
{ ism: "Aziza", holat: "nofaol" },
];
console.log(chiroyli(renderToStaticMarkup(<Royxat talabalar={talabalar} />)));
<ul>
<li>Malika - <b>Faol</b>
</li>
<li>Aziza - <b>Nofaol</b>
</li>
</ul>
Uch kichik komponent bitta kattasidan ko'ra yaxshiroq: har birini alohida o'qish, sinash va boshqa joyda ishlatish mumkin.
Aniq qoida yo'q, lekin uchta belgi bor:
- Takrorlanish - bir xil JSX ikki joyda uchrasa.
- Uzunlik - komponent ekranga sig'masa.
- Nom topilsa - bo'lakka yaxshi nom o'ylab topa olsangiz, demak u mustaqil tushuncha.
Teskarisi ham to'g'ri: har bir <div> ni alohida komponent
qilish kerak emas. Juda mayda bo'laklar kodni o'qishni
qiyinlashtiradi.
- Ikki komponent yozib, birini ikkinchisining ichiga joylang.
- Nomni kichik harf bilan boshlab, nima bo'lishini ko'ring.
- Props ni yoyish bilan va yoyishsiz yozing.
- Son, massiv va funksiya props larini uzating.
- Odatiy qiymatli komponent yozing.
childrenbilan o'rovchi komponent yasang.- Props ga JSX berib, ikkita "teshik" yarating.
- Props ni o'zgartirishga urinib ko'ring.
{...qolgani}bilan o'rovchiKirishyozing.- Katta komponentni uchta kichigiga bo'ling.
Xulosa #
- Komponent - katta harfli funksiya; kichik harf HTML tegi deb qabul qilinadi.
- Props yoyib olinadi:
function X({ ism, ball }). - Satrdan boshqa hamma qiymat jingalak qavsda beriladi.
- Odatiy qiymat - oddiy JavaScript parametri;
defaultPropsReact 19 da olib tashlangan. children- teglar orasidagi hamma narsa; qayta ishlatishning kaliti.- Props ga JSX berish mumkin - bir nechta "teshik" uchun.
- Props o'zgarmas: ma'lumot yuqoridan pastga oqadi.
{...props}faqat o'rovchi komponentlarda; qolgan joyda ochiq yozing.
Keyingi bo'limda ro'yxatlar va key ni o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.