16-bo‘lim

Kompozitsiya naqshlari

children bilan o'rash, props sifatida JSX, birlashtirilgan komponentlar, chizish funksiyasi va props burg'ulashni kompozitsiya bilan hal qilish.

🕑 10 daqiqa o‘qish 📄 595 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Sozlash emas, kompozitsiya
  2. Bir nechta joy
  3. Birlashtirilgan komponentlar
  4. Props burg'ulashni kompozitsiya bilan yechish
  5. Chizish funksiyasi
  6. Komponentni prop sifatida
  7. Naqshlarni tanlash
  8. Xulosa

React da qayta ishlatishning asosiy usuli - kompozitsiya: komponentlarni bir-birining ichiga joylash.

Bu bo'limda amalda uchraydigan naqshlarni ko'ramiz.

Sozlash emas, kompozitsiya #

JSX
import { renderToStaticMarkup } from "react-dom/server";
import { chiroyli } from "./dom-muhit.mjs";

function SozlanadiganPanel({ sarlavha, matn, tugmaMatni, tugmaBormi }) {
    return (
        <section>
            <h3>{sarlavha}</h3>
            <p>{matn}</p>
            {tugmaBormi && <button>{tugmaMatni}</button>}
        </section>
    );
}

function Panel({ sarlavha, children }) {
    return (
        <section>
            <h3>{sarlavha}</h3>
            {children}
        </section>
    );
}

console.log(chiroyli(renderToStaticMarkup(
    <SozlanadiganPanel
        sarlavha="Birinchi"
        matn="Matn"
        tugmaBormi
        tugmaMatni="Bosish"
    />,
)));

console.log("---");

console.log(chiroyli(renderToStaticMarkup(
    <Panel sarlavha="Ikkinchi">
        <p>Matn</p>
        <button>Bosish</button>
        <small>Va istalgan boshqa narsa</small>
    </Panel>,
)));
Natija
<section>
<h3>Birinchi</h3>
<p>Matn</p>
<button>Bosish</button>
</section>
---
<section>
<h3>Ikkinchi</h3>
<p>Matn</p>
<button>Bosish</button>
<small>Va istalgan boshqa narsa</small>
</section>

Natija bir xil, lekin ikkinchi yondashuv cheksiz moslashuvchan.

Props soni o'sib borsa, kompozitsiyaga o'ting

SozlanadiganPanel ni kengaytirish uchun har safar yangi prop kerak: ikonka, ikkinchi tugma, pastki matn, rang.

Bir yildan keyin unda yigirmata prop bo'ladi va ularning yarmi faqat bitta joyda ishlatiladi.

Panel esa hech qachon o'zgarmaydi: ichiga nima qo'ysangiz, o'sha chiziladi.

Oddiy belgi: prop nomida Bormi, Korinsinmi, Turi kabi so'zlar ko'paysa - bu kompozitsiyaga o'tish vaqti kelganini bildiradi.

Bir nechta joy #

JSX
import { renderToStaticMarkup } from "react-dom/server";
import { chiroyli } from "./dom-muhit.mjs";

function Kartochka({ boshi, tanasi, oyogi }) {
    return (
        <article>
            <header>{boshi}</header>
            <div className="tana">{tanasi}</div>
            {oyogi && <footer>{oyogi}</footer>}
        </article>
    );
}

console.log(chiroyli(renderToStaticMarkup(
    <Kartochka
        boshi={<h3>Malika</h3>}
        tanasi={<p>88 ball</p>}
        oyogi={<button>Batafsil</button>}
    />,
)));

console.log("---");

console.log(chiroyli(renderToStaticMarkup(
    <Kartochka boshi={<h3>Aziza</h3>} tanasi={<p>79 ball</p>} />,
)));
Natija
<article>
<header>
<h3>Malika</h3>
</header>
<div class="tana">
<p>88 ball</p>
</div>
<footer>
<button>Batafsil</button>
</footer>
</article>
---
<article>
<header>
<h3>Aziza</h3>
</header>
<div class="tana">
<p>79 ball</p>
</div>
</article>

children bitta joy beradi. Bir nechta joy kerak bo'lsa, JSX ni oddiy props sifatida uzatish mumkin.

Ikkinchi misolda oyogi berilmadi - undefined bo'lgani uchun footer umuman chizilmadi.

Birlashtirilgan komponentlar #

JSX
import { createContext, useContext, useState } from "react";

const YonalishKonteksti = createContext(null);

export function Yonalish({ children, boshlangich }) {
    const [faol, tanla] = useState(boshlangich);
    return (
        <YonalishKonteksti value={{ faol, tanla }}>
            <div className="yonalish">{children}</div>
        </YonalishKonteksti>
    );
}

export function Tugma({ nom, children }) {
    const { faol, tanla } = useContext(YonalishKonteksti);
    return (
        <button
            id={`t-${nom}`}
            className={faol === nom ? "faol" : ""}
            onClick={() => tanla(nom)}
        >
            {children}
        </button>
    );
}

export function Panel({ nom, children }) {
    const { faol } = useContext(YonalishKonteksti);
    if (faol !== nom) return null;
    return <div id={`p-${nom}`}>{children}</div>;
}
JSX
import { Yonalish, Tugma, Panel } from "./yonalish.mjs";
import { chiz, bos, html } from "./dom-muhit.mjs";

await chiz(
    <Yonalish boshlangich="profil">
        <Tugma nom="profil">Profil</Tugma>
        <Tugma nom="sozlama">Sozlamalar</Tugma>
        <Panel nom="profil">Profil mazmuni</Panel>
        <Panel nom="sozlama">Sozlama mazmuni</Panel>
    </Yonalish>,
);

const korinadigan = () =>
    document.querySelector("#p-profil") ? "profil" : "sozlama";

console.log("boshida:", korinadigan());
console.log("faol tugma:", document.querySelector(".faol").textContent);

await bos("#t-sozlama");
console.log("bosilgandan keyin:", korinadigan());
console.log("faol tugma:", document.querySelector(".faol").textContent);
Natija
boshida: profil
faol tugma: Profil
bosilgandan keyin: sozlama
faol tugma: Sozlamalar

Yonalish, Tugma va Panel birga ishlaydi, lekin foydalanuvchi ularni istalgan tartibda joylashtira oladi.

Ular bir-biri bilan kontekst orqali gaplashadi - props uzatish kerak emas.

Bu naqsh kutubxonalarda ko'p uchraydi

<Select> va <Option>, <Accordion> va <AccordionItem>, <Menu> va <MenuItem> - hammasi shu naqshda yozilgan.

Foydasi: moslashuvchanlik. Foydalanuvchi tugmalar orasiga ajratgich qo'yishi, ularni o'rashi yoki tartibini o'zgartirishi mumkin - komponentni o'zgartirmasdan.

Muqobil yondashuv - massiv berish:

JSX
<Yonalish bolimlar={[{ nom: "profil", mazmun: "..." }]} />

U soddaroq, lekin har bir yangi ehtiyoj uchun massiv shaklini kengaytirish kerak bo'ladi.

Props burg'ulashni kompozitsiya bilan yechish #

JSX
import { renderToStaticMarkup } from "react-dom/server";
import { chiroyli } from "./dom-muhit.mjs";

function Tugma({ mavzu }) {
    return <button className={mavzu}>Bosish</button>;
}

function YomonPanel({ mavzu }) {
    return <div><Tugma mavzu={mavzu} /></div>;
}

function YaxshiPanel({ children }) {
    return <div>{children}</div>;
}

const mavzu = "qorongi";

console.log(chiroyli(renderToStaticMarkup(<YomonPanel mavzu={mavzu} />)));
console.log("---");
console.log(chiroyli(renderToStaticMarkup(
    <YaxshiPanel>
        <Tugma mavzu={mavzu} />
    </YaxshiPanel>,
)));
Natija
<div>
<button class="qorongi">Bosish</button>
</div>
---
<div>
<button class="qorongi">Bosish</button>
</div>

Natija bir xil, lekin YaxshiPanel mavzu haqida hech narsa bilmaydi.

Kontekstdan oldin kompozitsiyani sinang

13-bo'limda props burg'ulash muammosini kontekst bilan yechgan edik. Lekin ko'pincha soddaroq yechim bor.

Element children sifatida uzatilsa, u yuqorida yaratiladi va kerakli props ni o'sha yerda oladi. Oradagi komponentlar uzatishda ishtirok etmaydi.

Bu kontekstdan afzalroq, chunki:

  1. Ma'lumot oqimi ochiq ko'rinadi;
  2. Qo'shimcha tuzilma kerak emas;
  3. Komponent mustaqil qoladi va sinash oson.

Kontekstni faqat kompozitsiya yordam bermaganda oling - masalan, ma'lumot juda chuqurda va ko'p joyda kerak bo'lganda.

Chizish funksiyasi #

JSX
import { renderToStaticMarkup } from "react-dom/server";
import { chiroyli } from "./dom-muhit.mjs";

function Royxat({ elementlar, chiz }) {
    return (
        <ul>
            {elementlar.map((element, i) => (
                <li key={element.id}>{chiz(element, i)}</li>
            ))}
        </ul>
    );
}

const talabalar = [
    { id: 1, ism: "Malika", ball: 88 },
    { id: 2, ism: "Husanboy", ball: 92 },
];

console.log(chiroyli(renderToStaticMarkup(
    <Royxat elementlar={talabalar} chiz={(t) => <b>{t.ism}</b>} />,
)));

console.log("---");

console.log(chiroyli(renderToStaticMarkup(
    <Royxat
        elementlar={talabalar}
        chiz={(t, i) => <span>{i + 1}. {t.ism} - {t.ball}</span>}
    />,
)));
Natija
<ul>
<li>
<b>Malika</b>
</li>
<li>
<b>Husanboy</b>
</li>
</ul>
---
<ul>
<li>
<span>1. Malika - 88</span>
</li>
<li>
<span>2. Husanboy - 92</span>
</li>
</ul>

Royxat qanday chizishni bilmaydi - buni chaqiruvchi hal qiladi.

Bu naqsh ro'yxat mantig'ini (kalitlar, bo'sh holat, sahifalash) bir marta yozib, ko'rinishni har joyda boshqacha qilish imkonini beradi.

Chizish funksiyasi bilan ehtiyot bo'ling

U kuchli, lekin kodni o'qishni qiyinlashtiradi: JSX ichida funksiya, uning ichida yana JSX.

Ko'pincha oddiyroq yechim bor - children bilan komponentni uzatish:

JSX
<Royxat elementlar={talabalar}>
    {(t) => <b>{t.ism}</b>}
</Royxat>

Yoki umuman ajratmasdan, har bir ro'yxat uchun alohida kichik komponent yozish.

Chizish funksiyasini faqat mantiq murakkab va ko'rinish har joyda boshqacha bo'lganda ishlating.

Komponentni prop sifatida #

JSX
import { renderToStaticMarkup } from "react-dom/server";

function Xabar({ Ikonka, matn }) {
    return (
        <div className="xabar">
            <Ikonka />
            <span>{matn}</span>
        </div>
    );
}

function Ogohlantirish() {
    return <b>!</b>;
}

function Muvaffaqiyat() {
    return <b>+</b>;
}

console.log(renderToStaticMarkup(
    <Xabar Ikonka={Ogohlantirish} matn="Diqqat" />));
console.log(renderToStaticMarkup(
    <Xabar Ikonka={Muvaffaqiyat} matn="Saqlandi" />));
Natija
<div class="xabar"><b>!</b><span>Diqqat</span></div>
<div class="xabar"><b>+</b><span>Saqlandi</span></div>

Komponentning o'zini prop sifatida uzatish mumkin.

Diqqat: prop nomi katta harf bilan - aks holda JSX uni HTML tegi deb biladi (4-bo'lim).

Naqshlarni tanlash #

EhtiyojNaqsh
Ichiga istalgan narsa qo'yishchildren
Bir nechta alohida joyJSX props
Birga ishlaydigan komponentlar to'plamiKontekst + kompozitsiya
Ko'rinishni tashqaridan boshqarishChizish funksiyasi
Ikonka yoki shakl almashtirishKomponent prop
Amaliy topshiriq
  1. Ko'p propsli komponentni children ga o'tkazing.
  2. Ikki alohida joyli kartochka yozing.
  3. Berilmagan joy chizilmasligini tekshiring.
  4. Birlashtirilgan yo'nalish komponentini yozing.
  5. Uning qismlarini tartibini o'zgartirib joylang.
  6. Props burg'ulashni kompozitsiya bilan yeching.
  7. Uni kontekst bilan ham yechib, ikkalasini solishtiring.
  8. Chizish funksiyasi bilan ro'yxat yozing.
  9. Bir xil ro'yxatni ikki xil ko'rinishda chizing.
  10. Ikonkani komponent prop sifatida uzating.

Xulosa #

  • Props soni o'sib borsa - kompozitsiyaga o'ting.
  • children bitta joy, JSX props bir nechta joy beradi.
  • Birga ishlaydigan komponentlar kontekst orqali gaplashadi va istalgan tartibda joylashadi.
  • Props burg'ulashni ko'pincha kompozitsiya hal qiladi - kontekstdan oldin shuni sinang.
  • Chizish funksiyasi kuchli, lekin o'qishni qiyinlashtiradi.
  • Komponentni prop sifatida uzatganda nom katta harfli bo'lsin.

Keyingi bo'limda unumdorlikni o'rganamiz.

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.