Mundarija (32)
- Bu darsda
- 1. Nega bu kerak?
- 2. Props qanday uzatiladi
- 2.1 Bitta obyekt
- 2.2 Parametrda destructuring
- 2.3 Qo'shtirnoq yoki jingalak qavs
- 3. Default qiymat va boolean props
- 3.1 Berilmagan prop — undefined
- 3.2 Boolean props
- 4. Props faqat o'qiladi
- 4.1 O'zgartirishga urinish
- 4.2 Nega bunday qoida
- 5. Spread: {...props}
- 5.1 Obyektni props qilib yoyish
- 5.2 Qolganini uzatish: ...rest
- 5.3 Tuzoq: DOM'ga begona prop tushadi
- 6. Maxsus props: key va ref
- 6.1 key komponentga yetib bormaydi
- 6.2 ref — React 19 da oddiy prop
- 6.3 Props nomlari
- 7. Funksiya ham prop
- 8. Props'ga tur yozamiz
- 9. Vazifalar qadami: AmalTugmasi
- 10. Ko'p uchraydigan xatolar
- 11. Mashqlar
- 1-mashq (oson): ekranda nima chiqadi?
- 2-mashq (o'rta): menyu kartasi
- 3-mashq (qiyin): buyurtma qatori (TypeScript)
- 4-mashq: Vazifalar qadami
- 12. Real ishda
- Xulosa
- Manbalar
Props: komponentga ma'lumot uzatish — destructuring, default qiymat, spread va funksiya props
Qisqacha: Props — ota komponent bolaga beradigan qiymatlar:
<MenuCard name="Osh" price={35000} />. React ularni bitta obyektga yig'ib, komponentga birinchi argument qilib beradi. Odatda parametrdayoq ajratib olinadi:function MenuCard({ name, price, currency = "so'm" }). Props faqat o'qiladi: komponent ularni o'zgartirmaydi, React dev rejimda bu obyektni muzlatib qo'yadi. Qiymat sifatida istalgan narsa — satr, son, boolean, obyekt, hatto funksiya ham berilishi mumkin.
Bu darsda
- Komponentga props berasiz va uni parametrda destructuring bilan olasiz.
- Satr va
{}dagi qiymat farqini, default qiymat va boolean props'ni bilasiz. - Props nega faqat o'qilishini va uni o'zgartirmoqchi bo'lsa nima bo'lishini ko'rasiz.
{...props}spread bilan props uzatasiz va uning tuzog'ini taniysiz.- Props'ga TypeScript turi yozasiz va uchta eng ko'p uchraydigan tip xatosini o'qiysiz.
Oldin bilishingiz kerak: Komponentlar: yaratish, nomlash va fayllarga ajratish, Parametrda destructuring va options obyekti, Spread va rest operatori.
1. Nega bu kerak?
Oldingi dars mashqida MenuCard uch marta chiqdi — uchalasida ham "Osh — 35000 so'm". Komponent bitta, taom esa har xil bo'lishi kerak. Har taomga alohida OshCard, MantiCard yozish — nusxa ko'chirish, ya'ni xato manbai.
Vanilla'da bu muammoni funksiya argumentlari bilan yechardik. vazifalar dagi tugmaYasa(amal, matn, nomi) bitta funksiya, lekin har chaqiruvda boshqa tugma yasaydi: "Tahrirlash", "O'chirish", "Saqlash". Parametrlar va argumentlar darsidagi g'oya.
React'da argumentlarning nomi — props (properties — "xususiyatlar"). Ularni HTML atributi kabi yozasiz. Hayotiy o'xshatish: oshxonadagi buyurtma varaqasi. Oshpaz bitta retsept bilan ishlaydi, varaqada esa "osh, 2 porsiya, piyozsiz" deb yozilgan. Retsept — komponent, varaqa — props.
2. Props qanday uzatiladi
2.1 Bitta obyekt
Props atributlar kabi yoziladi va React ularni bitta obyektga yig'adi. Komponent uni birinchi argument qilib oladi:
function MenuCard(props) {
console.log(props);
return (
<li>
{props.name} — {props.price} so'm
</li>
);
}
function App() {
return (
<ul>
<MenuCard name="Osh" price={35000} />
</ul>
);
}Konsolda:
{name: 'Osh', price: 35000}Ekranda:
Osh — 35000 so'mJSX I darsida ko'rgandik: <MenuCard name="Osh" price={35000} /> → jsx(MenuCard, { name: "Osh", price: 35000 }). Ikkinchi argument — o'sha obyekt. React komponentni chaqirganda uni props parametriga beradi.
2.2 Parametrda destructuring
Har safar props. yozish noqulay. Odatda obyekt parametrdayoq ajratib olinadi (parametrda destructuring):
function MenuCard({ name, price }) {
return (
<li>
{name} — {price} so'm
</li>
);
}
function App() {
return (
<ul>
<MenuCard name="Osh" price={35000} />
<MenuCard name="Lag'mon" price={28000} />
<MenuCard name="Manti" price={30000} />
</ul>
);
}Ekranda:
Osh — 35000 so'm
Lag'mon — 28000 so'm
Manti — 30000 so'mBitta funksiya — uch xil karta. Parametr qatoridan komponent nimani kutishi ham darhol ko'rinadi: name va price. Kursda va vazifalar da hamma joyda shu shakl.
2.3 Qo'shtirnoq yoki jingalak qavs
Qo'shtirnoqdagi qiymat — har doim satr. Son, boolean, obyekt yoki o'zgaruvchi kerak bo'lsa — {}:
function PriceTest({ price }) {
return (
<p>
{typeof price}: {price + 5000}
</p>
);
}
function App() {
return (
<div>
<PriceTest price="35000" />
<PriceTest price={35000} />
</div>
);
}Ekranda:
string: 350005000
number: 40000Birinchisida "35000" + 5000 — satrga satr ulandi (Yashirin coercion darsidagi tuzoq). Xato chiqmadi, faqat noto'g'ri son. TypeScript buni ushlaydi — «Props'ga tur yozamiz» bo'limida ko'ramiz.
Tekshirib ko'ring:
<MenuCard name={"Osh"} />va<MenuCard name="Osh" />farqi bormi?<MenuCard dish={{ name: "Osh" }} />dagi ikki juft qavs nima?
Javob
Birinchi juftlikda farq yo'q — ikkalasi ham satr. Satr uchun qo'shtirnoq qisqaroq. Ikki juft qavs: tashqisi — "bu yerda JavaScript", ichkisi — obyekt literali. Ya'ni dish ga { name: "Osh" } obyekti beriladi. JSX I dagi style={{ … }} ham aynan shunday edi.
3. Default qiymat va boolean props
3.1 Berilmagan prop — undefined
Ota komponent ba'zi props'ni bermasligi mumkin. Unda u undefined bo'ladi. Destructuring'dagi default qiymat shu holat uchun:
function Price({ value = 0, currency = "so'm" }) {
return (
<p>
{value} {currency}
</p>
);
}
function App() {
return (
<div>
<Price value={35000} />
<Price value={5} currency="$" />
<Price />
</div>
);
}Ekranda:
35000 so'm
5 $
0 so'mDefault faqat undefined da ishlaydi (Obyekt destructuring dagi qoida). value={null} bersangiz — default olinmaydi, null esa ekranda hech narsa chizmaydi. Shuning uchun "qiymat yo'q" holatini undefined (ya'ni prop'ni umuman yozmaslik) bilan bildirish qulay.
3.2 Boolean props
Qiymatsiz yozilgan atribut — true:
function MenuCard({ name, isNew = false, soldOut = false }) {
return (
<li>
{name}
{isNew && " · Yangi!"}
{soldOut && " · Tugadi"}
</li>
);
}
function App() {
return (
<ul>
<MenuCard name="Manti" isNew />
<MenuCard name="Somsa" soldOut={true} />
<MenuCard name="Osh" isNew={false} />
</ul>
);
}Ekranda:
Manti · Yangi!
Somsa · Tugadi
OshisNew — isNew={true} ning qisqa shakli, HTML'dagi disabled kabi. Boolean props nomi odatda savolga o'xshaydi: isNew, soldOut, hasDiscount. Bu yerda && chapida — haqiqiy boolean. Shuning uchun JSX II dagi 0 tuzog'i yo'q.
4. Props faqat o'qiladi
4.1 O'zgartirishga urinish
Sardor narxni chegirma bilan ko'rsatmoqchi bo'ldi va props'ning o'zini o'zgartirdi:
function MenuCard(props) {
props.price = props.price * 0.9; // ❌ 10% chegirma
return (
<li>
{props.name} — {props.price} so'm
</li>
);
}
function App() {
return <MenuCard name="Osh" price={35000} />;
}Konsolda:
Uncaught TypeError: Cannot assign to read only property 'price' of object '#<Object>'"Faqat o'qiladigan price xususiyatiga yozib bo'lmaydi." Saytda «Komponentni chizishda xato» qutisi chiqadi: Komponentlar: App → MenuCard. React dev rejimda props obyektini Object.freeze bilan muzlatadi. Modul kodi esa JavaScript'ning strict mode ida ishlaydi (React'ning StrictMode komponenti bilan adashtirmang) — muzlatilgan obyektga yozish jim o'tmaydi, xato tashlaydi.
To'g'ri yo'l — yangi lokal o'zgaruvchi:
function MenuCard({ name, price }) {
const salePrice = price * 0.9;
return (
<li>
{name} — {salePrice} so'm
</li>
);
}
function App() {
return <MenuCard name="Osh" price={35000} />;
}Ekranda:
Osh — 31500 so'mProduction build'da React props'ni muzlatmaydi — tezlik uchun. Xato tashlanmaydi, lekin kod baribir noto'g'ri. Linter ikkala holatda ham ushlaydi. eslint-plugin-react-hooks 7.1.1 (react-hooks/immutability qoidasi, chiqish qisqartirilgan):
2:3 error Error: This value cannot be modified
Modifying component props or hook arguments is not allowed. Consider using a local variable instead."Komponent props'ini yoki hook argumentlarini o'zgartirib bo'lmaydi. O'rniga lokal o'zgaruvchi ishlating."
4.2 Nega bunday qoida
Props — ota komponentning ma'lumoti. Bola uni faqat o'qiydi, xuddi ofitsiant buyurtma varaqasini o'qiganidek. Ofitsiant varaqadagi "2 porsiya" ni o'chirib "3" deb yozsa — oshxona chalkashadi. React'da ham shunday: props o'zgarsa, React buni bilmaydi va ekran ma'lumotdan ajralib qoladi.
Props'ni ota o'zgartiradi — yangi qiymat bilan qayta chizib. Quyidagi blokda ota (vanilla draw()) har bosishda MenuCard ga boshqa taom beradi. Blok tugmani ikki marta o'zi bosadi:
import { createRoot } from "react-dom/client";
const dishes = [
{ name: "Osh", price: 35000 },
{ name: "Lag'mon", price: 28000 },
{ name: "Manti", price: 30000 },
];
const root = createRoot(document.getElementById("root"));
let index = 0;
function MenuCard({ name, price }) {
console.log("MenuCard chizildi:", name);
return <p>{name} — {price} so'm</p>;
}
function draw() {
const dish = dishes[index];
root.render(
<div>
<MenuCard name={dish.name} price={dish.price} />
<button onClick={() => {
index = (index + 1) % dishes.length;
draw();
}}>
Keyingi taom
</button>
</div>
);
}
draw();Konsolda:
MenuCard chizildi: Osh
MenuCard chizildi: Lag'mon
MenuCard chizildi: MantiEkranda:
Manti — 30000 so'm
Keyingi taom| Qadam | Ota beradi (props) | Ekranda |
|---|---|---|
| birinchi chizish | {name: "Osh", price: 35000} |
Osh — 35000 so'm |
| «Keyingi taom» | {name: "Lag'mon", price: 28000} |
Lag'mon — 28000 so'm |
| «Keyingi taom» | {name: "Manti", price: 30000} |
Manti — 30000 so'm |
MenuCard hech narsani o'zgartirmadi — har safar yangi props bilan qayta chaqirildi.
flowchart TD
P["Ota: draw()"] -- "props: name, price" --> C["MenuCard"]
C -- "JSX" --> E["Ekran"]
C -. "o'zgartira olmaydi" .-> PDiagrammaga qarang: props faqat bir yo'nalishda — otadan bolaga oqadi. Bola ekranni yasaydi, lekin otaning ma'lumotiga tega olmaydi (punktir). Bu UI = f(state) ning kichik nusxasi: komponent — props'dan ekran yasaydigan funksiya. Ma'lumot faqat yuqoridan pastga oqadi.
Tekshirib ko'ring:
function Badge({ text }) { text = text.toUpperCase(); return <b>{text}</b>; }— bu ham props'ni o'zgartirishmi? Xato chiqadimi?
Javob
Yo'q, xato chiqmaydi. text — destructuring yaratgan lokal o'zgaruvchi, props obyektining o'zi emas. Unga yangi qiymat yozish props'ga tegmaydi. Lekin o'qishga qulayroq yo'l — yangi nom: const upper = text.toUpperCase();. Shunda "kelgan qiymat" va "hisoblangan qiymat" chalkashmaydi.
5. Spread: {...props}
5.1 Obyektni props qilib yoyish
Ma'lumot ko'pincha tayyor obyekt bo'lib keladi. Uni maydonma-maydon yozish o'rniga spread bilan yoyish mumkin:
const dish = { name: "Manti", price: 30000, isNew: true };
function MenuCard({ name, price, isNew }) {
return (
<li>
{name} — {price} so'm{isNew && " · Yangi!"}
</li>
);
}
function App() {
return (
<ul>
<MenuCard {...dish} />
<MenuCard {...dish} price={27000} />
</ul>
);
}Ekranda:
Manti — 30000 so'm · Yangi!
Manti — 27000 so'm · Yangi!{...dish} = name="Manti" price={30000} isNew={true}. Tartib muhim: keyingisi oldingisini ustidan yozadi, obyekt spread'dagidek. Ikkinchi kartada price={27000} spread'dan keyin turibdi — shuning uchun u yutdi.
5.2 Qolganini uzatish: ...rest
Rest bilan "keraklisini olib, qolganini uzatish" mumkin. Masalan, umumiy tugma komponenti. U label ni o'zi ishlatadi, qolgan atributlarni esa <button> ga beradi:
function ActionButton({ label, ...rest }) {
return (
<button type="button" {...rest}>
{label}
</button>
);
}
function App() {
return (
<div>
<ActionButton label="Saqlash" title="Ctrl+S" />
<ActionButton label="Yuborish" type="submit" />
<ActionButton label="Tugadi" disabled />
</div>
);
}Ekranda:
SaqlashYuborishTugadititle, type, disabled — ActionButton ularni bilmaydi ham, faqat uzatadi. type="button" spread'dan oldin turibdi — bu standart qiymat: kerak bo'lsa, chaqiruvchi type="submit" bilan almashtiradi.
5.3 Tuzoq: DOM'ga begona prop tushadi
Hamma narsani ko'r-ko'rona uzatish — xavfli:
function MenuCard(props) {
return <li {...props}>Manti</li>;
}
function App() {
return (
<ul>
<MenuCard isNew />
</ul>
);
}Konsolda:
React does not recognize the `isNew` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `isnew` instead. If you accidentally passed it from a parent component, remove it from the DOM element.Ekranda:
Manti"React DOM elementidagi isNew prop'ini tanimaydi. Ataylab DOM'da maxsus atribut bo'lishini istasangiz — kichik harf bilan isnew yozing. Ota komponentdan tasodifan o'tib kelgan bo'lsa — uni DOM elementidan olib tashlang." isNew komponent uchun edi, <li> uchun emas. Qoida: o'zingiz ishlatadigan props'ni destructuring bilan ajrating, <li> ga faqat ...rest ni bering.
Tekshirib ko'ring:
<ActionButton label="Saqlash" type="submit" />daActionButtonichida{...rest} type="button"deb yozilgan bo'lsa (spread oldin), tugma turi qanday bo'ladi?
Javob
"button". Keyin yozilgan atribut yutadi: spread type="submit" ni qo'ydi, keyingi type="button" uni ustidan yozdi. Chaqiruvchi endi turni o'zgartira olmaydi. Standart qiymat spread'dan oldin, majburiy qiymat esa keyin yoziladi.
6. Maxsus props: key va ref
6.1 key komponentga yetib bormaydi
Ikkita atribut React'ning o'ziga tegishli. Ulardan biri — key (JSX II da ro'yxatda ko'rgandik). U props obyektiga kirmaydi:
function MenuCard(props) {
console.log(props, props.key);
return <li>{props.name}</li>;
}
function App() {
return (
<ul>
<MenuCard key="osh" name="Osh" />
</ul>
);
}Konsolda:
MenuCard: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)
{name: 'Osh'} undefinedEkranda:
Osh"MenuCard: key — prop emas. Uni o'qishga urinish undefined qaytaradi. Bola komponentga shu qiymat kerak bo'lsa — uni boshqa nom bilan alohida prop qilib bering." key — React uchun yorliq: "bu qaysi element?". Komponentga esa u kerak emas. Id kerak bo'lsa — ikki marta bering: <MenuCard key={dish.id} id={dish.id} />. Buning sababini Ro'yxatlar va key darsida ko'ramiz.
6.2 ref — React 19 da oddiy prop
Ikkinchi maxsus atribut — ref, DOM elementiga to'g'ridan-to'g'ri murojaat uchun. React 18 gacha u ham props'ga kirmasdi va buning uchun forwardRef degan maxsus funksiya kerak edi. React 19 dan boshlab ref komponentga oddiy prop bo'lib keladi. Eski kodda forwardRef ni ko'rasiz — uni useRef II: DOM elementlari va ref prop darsida o'rganamiz.
6.3 Props nomlari
| Nima | Qoida | Misol |
|---|---|---|
| oddiy qiymat | camelCase, ot | name, price, dishName |
| boolean | savol shaklida | isNew, soldOut, hasDiscount |
| hodisa (funksiya) | on + fe'l |
onOrder, onDelete |
| HTML atributi nomi | DOM'dagidek | className, htmlFor, disabled |
class, for kabi JavaScript kalit so'zlarini prop nomi qilmang — JSX I dagi className sababi shu. key va ref nomlari ham band.
7. Funksiya ham prop
Props'ga istalgan qiymat beriladi — funksiya ham. Masalan, narxni qanday ko'rsatishni ota hal qilsin:
function PriceTag({ price, format = (n) => `${n} so'm` }) {
return <p>Narx: {format(price)}</p>;
}
function App() {
return (
<div>
<PriceTag price={35000} />
<PriceTag
price={35000}
format={(n) => `${n / 1000} ming so'm`}
/>
</div>
);
}Ekranda:
Narx: 35000 so'm
Narx: 35 ming so'mBu callback g'oyasi. PriceTag funksiyani o'zi tanlamaydi — tashqaridan oladi. Eng ko'p ishlatiladigan funksiya props — hodisalar: onClick, onChange. "Tugma bosilganda nima qilish" ni bola emas, ota biladi. Ularni Hodisalarni boshqarish darsida yozamiz.
8. Props'ga tur yozamiz
vazifalar — TypeScript'da. Props ham turi bilan yoziladi:
type MenuCardProps = {
name: string;
price: number;
isNew?: boolean; // ? — ixtiyoriy
};
function MenuCard({ name, price, isNew = false }: MenuCardProps) {
return (
<li>
{name} — {price} so'm{isNew && " · Yangi!"}
</li>
);
}
export default function App() {
return (
<ul>
<MenuCard name="Manti" price={30000} isNew />
</ul>
);
}Ekranda:
Manti — 30000 so'm · Yangi!type — obyekt turlari darsidagidek. Endi uchta ko'p uchraydigan xato kompilyatsiyadayoq ushlanadi:
type MenuCardProps = {
name: string;
price: number;
isNew?: boolean;
};
function MenuCard({ name, price, isNew = false }: MenuCardProps) {
return <li>{name} {price} {isNew && "Yangi"}</li>;
}
export function App() {
return (
<ul>
<MenuCard name="Osh" />
<MenuCard name="Manti" price="30000" />
<MenuCard name="Choy" price={5000} prise={5000} />
</ul>
);
}Xato:
TS2741: Property 'price' is missing in type '{ name: string; }' but required in type 'MenuCardProps'.
TS2322: Type 'string' is not assignable to type 'number'.
TS2322: Type '{ name: string; price: number; prise: number; }' is not assignable to type 'IntrinsicAttributes & MenuCardProps'.
Property 'prise' does not exist on type 'IntrinsicAttributes & MenuCardProps'. Did you mean 'price'?Uchala xato tarjimasi:
- TS2741 — "
pricexususiyati{ name: string; }da yo'q, lekinMenuCardPropsda majburiy." Prop unutilgan. - TS2322 — "
stringturininumberga berib bo'lmaydi." Bu — «Qo'shtirnoq yoki jingalak qavs» bo'limidagi"350005000"xatosi, endi ishga tushmasdan ushlandi. - TS2322 — "
prisexususiyati … turida yo'q.pricedemoqchimidingiz?" Imlo xatosi.IntrinsicAttributes— React har komponentga qo'shadigan maxsus props (masalan,key).
Props turlarining chuqur tomonlari (children turi, ComponentProps<"button">, generic) — React + TS I: props va children turlari darsida.
Tekshirib ko'ring:
isNew?: booleandan?ni olib tashlasak,<MenuCard name="Osh" price={35000} />qatori nima bo'ladi?isNew = falsedefault qiymati endi kerakmi?
Javob
? siz isNew majburiy bo'ladi — prop'siz qator TS2741: Property 'isNew' is missing … beradi. Har chaqiruvda isNew={false} yozishga to'g'ri keladi. Default qiymat esa ma'nosini yo'qotadi: majburiy prop hech qachon undefined bo'lmaydi. Qoida: ko'p joyda bir xil qiymat bo'ladigan prop — ixtiyoriy va default bilan, har doim har xil bo'ladigani — majburiy.
9. Vazifalar qadami: AmalTugmasi
refactor/royxat-react branch'ida birinchi komponentni yozamiz. v6 dagi tugmaYasa() ni eslang:
function tugmaYasa(
amal: Amal,
matn: string,
nomi: string,
): HTMLButtonElement {
const tugma = document.createElement("button");
tugma.type = "button";
tugma.dataset.amal = amal;
tugma.textContent = matn;
tugma.setAttribute("aria-label", `${matn}: ${nomi}`);
return tugma;
}Uch argument — uchta prop. Yangi fayl src/AmalTugmasi.tsx:
// AmalTugmasi.tsx — qatordagi tugma (17/#06: props). Ekran
// o'quvchi "Tahrirlash" emas, "Tahrirlash: Non olish" eshitadi —
// qaysi vazifa ekani aria-label'da
export type Amal =
"almashtir" | "ochir" | "tahrirla" | "saqla" | "bekor";
type Props = {
amal: Amal;
matn: string; // tugmada ko'rinadigan so'z
nomi: string; // vazifa matni
};
export function AmalTugmasi({ amal, matn, nomi }: Props) {
return (
// data-amal — vanilla hodisa tinglovchisi shunga qaraydi
// (#11 gacha)
<button
type="button"
data-amal={amal}
aria-label={`${matn}: ${nomi}`}
>
{matn}
</button>
);
}Qatorma-qator:
Amal— literal turlar birlashmasi:amalfaqat beshta so'zdan biri.amal="ochirish"yozilsa,tscdarhol aytadi.render.tsdagiAmalturi shu faylga ko'chdi.aria-label={`${matn}: ${nomi}`}— template literal props ichida,{}bilan. Malika ekran o'quvchida tugmani "O'chirish: Non olish" deb eshitadi. Faqat "O'chirish" — qaysi vazifa ekani noma'lum (Dinamik UI'da qulaylik).data-amal={amal}— vanilla'dagidataset.amal. JSX'dadata-*atributlari aynan HTML'dagidek yoziladi, chiziqcha bilan. Bosishni hozircha vanilla delegatsiya ushlaydi (Event delegation) va shu atributga qaraydi. Hodisalarni boshqarish darsida uonClickga almashadi.type="button"— formada tasodifan "yuborish" bo'lmasin; Bobur Enter bosganda ham.- Izoh JSX ichida emas,
return (dan keyin —//izoh<buttondan oldin, JavaScript qismida turibdi. JSX ichida izoh{/* … */}bo'lardi (JSX II).
.bind(null, "tahrirla", "Tahrirlash") bilan yasalgan to'rtta yordamchi (tahrirTugmasi va boshqalar) endi kerak emas. Ularning o'rnida JSX'da props bilan yozamiz: <AmalTugmasi amal="tahrirla" matn="Tahrirlash" nomi={vazifa.matn} />.
Tekshiruv: npm run tip jim tugaydi. Komponent hali hech qayerda ishlatilmayapti — ekranda hech narsa o'zgarmadi. U children va Shartli render darslarida qatorlarga qo'yiladi. Commit — Ro'yxatlar va key darsida.
10. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
350005000 kabi son |
price="35000" — satr |
price={35000} |
read only property |
props'ga yozish | lokal o'zgaruvchi |
does not recognize the … prop |
{...props} DOM elementiga |
o'zingiznikini ajrating, ...rest |
| default ishlamadi | prop null berildi |
prop'ni yozmang (undefined) |
TS2741 … is missing |
majburiy prop berilmagan | bering yoki ? qiling |
`key` is not a prop |
bolada props.key o'qilgan |
alohida prop: id={…} |
Did you mean 'price'? |
prop nomida imlo xatosi | nomni tuzating |
11. Mashqlar
Mashqlar kurs/mashqlar/17/06-props/ da. Har yechimni «Ishga tushir» bilan sinang.
1-mashq (oson): ekranda nima chiqadi?
Kodni ishga tushirmasdan oldin har qatorni ayting.
function Line({ label, count = 1, unit = "porsiya" }) {
return (
<p>
{label}: {count + 1} {unit}
</p>
);
}
function App() {
return (
<div>
<Line label="A" count={2} />
<Line label="B" count="2" />
<Line label="C" />
<Line label="D" count={0} unit="ta" />
</div>
);
}- B qatorida,
B:dan keyin: - C qatorida,
C:dan keyin:
Yechim
Ekranda:
A: 3 porsiya
B: 21 porsiya
C: 2 porsiya
D: 1 taA — son, 2 + 1. B — qo'shtirnoq, satr: "2" + 1 → "21". C — count berilmagan, default 1 ishladi. D — 0 berilgan, default ishlamaydi (0 — undefined emas), 0 + 1 → 1.
2-mashq (o'rta): menyu kartasi
MenuCard komponentini yozing. Props: name, price, isNew (boolean, default false), currency (default "so'm"). Yangi taomda nomdan keyin " · Yangi!" chiqsin. App to'rtta karta chizsin: osh (35000), manti (30000, yangi), ko'k choy (5000) va lag'mon (28000). Lag'mon narxi dollarda: price={2.2}, currency="$". Ekranda shunday bo'lsin:
Osh — 35000 so'm
Manti · Yangi! — 30000 so'm
Ko'k choy — 5000 so'm
Lag'mon — 2.2 $Ishora: «Default qiymat va boolean props» bo'limidagi ikkita misolni birlashtiring.
Yechim
function MenuCard({ name, price, isNew = false, currency = "so'm" }) {
return (
<li>
{name}
{isNew && " · Yangi!"} — {price} {currency}
</li>
);
}
function App() {
return (
<ul>
<MenuCard name="Osh" price={35000} />
<MenuCard name="Manti" price={30000} isNew />
<MenuCard name="Ko'k choy" price={5000} />
<MenuCard name="Lag'mon" price={2.2} currency="$" />
</ul>
);
}Ekranda:
Osh — 35000 so'm
Manti · Yangi! — 30000 so'm
Ko'k choy — 5000 so'm
Lag'mon — 2.2 ${isNew && " · Yangi!"} va — {price} orasidagi qator ko'chishi — JSX uni bitta bo'shliqqa aylantiradi (JSX I). Shuning uchun nomdan keyin " — " to'g'ri chiqdi.
3-mashq (qiyin): buyurtma qatori (TypeScript)
OrderLine komponentini .tsx da yozing. Props turi:
dish—{ name: string; price: number }obyekti;count— son;formatPrice— ixtiyoriy funksiya(n: number) => string, default —(n) => `${n} so'm`;highlighted— ixtiyoriy boolean:truebo'lsa<li>gaclassName="ajratilgan", aks holda klass yo'q (undefined).
Ekranda: Osh × 2 = 70000 so'm. App uchta qator chizsin: osh × 2 (ajratilgan), manti × 3, ko'k choy × 4 — oxirgisi formatPrice bilan "20 ming so'm" ko'rinishida. Ishora: ixtiyoriy prop — ?: (Obyekt turlari), funksiya turi — Funksiyalarni tiplash.
Yechim
type Dish = { name: string; price: number };
type OrderLineProps = {
dish: Dish;
count: number;
formatPrice?: (n: number) => string;
highlighted?: boolean;
};
function OrderLine({
dish,
count,
formatPrice = (n) => `${n} so'm`,
highlighted = false,
}: OrderLineProps) {
return (
<li className={highlighted ? "ajratilgan" : undefined}>
{dish.name} × {count} = {formatPrice(dish.price * count)}
</li>
);
}
export default function App() {
return (
<ul>
<OrderLine
dish={{ name: "Osh", price: 35000 }}
count={2}
highlighted
/>
<OrderLine dish={{ name: "Manti", price: 30000 }} count={3} />
<OrderLine
dish={{ name: "Ko'k choy", price: 5000 }}
count={4}
formatPrice={(n) => `${n / 1000} ming so'm`}
/>
</ul>
);
}Ekranda:
Osh × 2 = 70000 so'm
Manti × 3 = 90000 so'm
Ko'k choy × 4 = 20 ming so'mDefault funksiyada n ning turi yozilmagan — TypeScript uni formatPrice?: (n: number) => string dan o'zi chiqaradi. className={… ? "ajratilgan" : undefined}: undefined bo'lsa React atributni umuman qo'ymaydi. Bo'sh satr "" bersangiz edi, class="" qolardi.
4-mashq: Vazifalar qadami
src/AmalTugmasi.tsx ni «Vazifalar qadami» bo'limidagidek yozing. npm run tip toza bo'lsin. Keyin sinab ko'ring: faylning oxiriga vaqtinchalik qator qo'shing — const sinov = <AmalTugmasi amal="ochirish" matn="O'chirish" nomi="Non" />;. tsc nima deydi? Sinovdan keyin qatorni o'chiring.
Yechim
tsc amal qiymatini rad etadi — "ochirish" Amal birlashmasida yo'q:
TS2322: Type '"ochirish"' is not assignable to type 'Amal'.Literal tur aynan shu uchun: e2e ssenariy va vanilla tinglovchi data-amal="ochir" ni kutadi. Bitta harf farqi bilan tugma ishlamay qolardi, endi esa kompilyatsiyada ushlanadi. Qolgan tekshiruvlar — branch oxirida, Ro'yxatlar va key darsida.
12. Real ishda
- Dizayn tizimlari (kompaniyaning umumiy tugma, karta, modal komponentlari) props bilan sozlanadi:
<Button variant="primary" size="sm" disabled>. Yaxshi komponent — kam va aniq props (Komponent API'sini loyihalash). ...restuzatish — kutubxona komponentlarida kundalik naqsh: tugma o'ramlariaria-*,data-*,titleni pastga o'tkazib yuboradi.- TypeScript'da props turi — ishda deyarli majburiy. Kod ko'rigida birinchi qaraladi: majburiy va ixtiyoriy props to'g'ri belgilanganmi.
- Intervyu savollari: "Props va state farqi?" (state — keyingi darslarda), "Bola komponent props'ni o'zgartira oladimi?", "
{...props}qanday tuzoqqa olib keladi?".
Xulosa
- Props — ota bolaga beradigan qiymatlar; React ularni bitta obyektga yig'ib, birinchi argument qilib beradi.
- Parametrda destructuring:
({ name, price, currency = "so'm" }); default faqatundefinedda ishlaydi. - Qo'shtirnoq — satr,
{}— istalgan JavaScript qiymat; qiymatsiz atribut —true. - Props faqat o'qiladi: dev rejimda muzlatilgan, o'zgartirish
TypeErrorberadi; yangi qiymatni ota yangi render bilan beradi. {...obj}va...restqulay, lekin DOM elementiga begona prop tushirmang.vazifalarda birinchi komponent —AmalTugmasi: uch argumentli funksiya uch props'li komponentga aylandi.
Keyingi dars: children va kompozitsiya — komponent ichiga boshqa JSX qo'yishni o'rganamiz va vazifalar qatorining <li> qobig'ini yasaymiz.
Manbalar
- React: "Passing Props to a Component" — react.dev/learn/passing-props-to-a-component
- React: "Keeping Components Pure" (props faqat o'qiladi) — react.dev/learn/keeping-components-pure
- React: "Unknown Prop Warning" — react.dev/warnings/unknown-prop
eslint-plugin-react-hooks—immutabilityqoidasi — react.dev/reference/eslint-plugin-react-hooks
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!