9-bo‘lim

Holatni ko'tarish

Umumiy holatni ota-komponentga ko'chirish, bolaga funksiya uzatish, yagona haqiqat manbai va holatni qayerga qo'yish.

🕑 8 daqiqa o‘qish 📄 552 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Muammo
  2. Yechim: holatni yuqoriga ko'chirish
  3. Boshqariladigan bola
  4. Yagona haqiqat manbai
  5. key bilan qayta yaratish
  6. Holatni qayerga qo'yish
  7. Xulosa

Ikki komponent bir xil ma'lumotga muhtoj bo'lsa, holat ularning umumiy otasiga ko'chiriladi. Bu naqsh holatni ko'tarish deb ataladi.

Muammo #

Ikki komponentda alohida holat bo'lsa, ular bir-birini ko'rmaydi:

JSX
import { useState } from "react";
import { chiz, bos, matn } from "./dom-muhit.mjs";

function Panel({ nom }) {
    const [soni, ozgartir] = useState(0);
    return (
        <button id={nom} onClick={() => ozgartir(soni + 1)}>
            {nom}: {soni}
        </button>
    );
}

function Ikkita() {
    return (
        <div>
            <Panel nom="chap" />
            <Panel nom="ong" />
        </div>
    );
}

await chiz(<Ikkita />);
await bos("#chap");
await bos("#chap");
console.log(matn("#chap"), "|", matn("#ong"));
Natija
chap: 2 | ong: 0

Har bir Panel o'z holatini saqlaydi. Ular mustaqil - ba'zan aynan shu kerak.

Lekin ikkalasi bir xil sonni ko'rsatishi kerak bo'lsa, bu yondashuv ishlamaydi.

Yechim: holatni yuqoriga ko'chirish #

JSX
import { useState } from "react";
import { chiz, bos, matn } from "./dom-muhit.mjs";

function Panel({ nom, soni, oshir }) {
    return (
        <button id={nom} onClick={oshir}>
            {nom}: {soni}
        </button>
    );
}

function Ikkita() {
    const [soni, ozgartir] = useState(0);

    function oshir() {
        ozgartir((oldingi) => oldingi + 1);
    }

    return (
        <div>
            <Panel nom="chap" soni={soni} oshir={oshir} />
            <Panel nom="ong" soni={soni} oshir={oshir} />
        </div>
    );
}

await chiz(<Ikkita />);
console.log(matn("#chap"), "|", matn("#ong"));

await bos("#chap");
await bos("#ong");
console.log(matn("#chap"), "|", matn("#ong"));
Natija
chap: 0 | ong: 0
chap: 2 | ong: 2

Endi ikkalasi ham bir xil sonni ko'rsatadi, va qaysi tugma bosilishidan qat'i nazar ikkalasi birga yangilanadi.

Ikki narsa o'zgardi:

  1. Holat otaga ko'chdi.
  2. Bola qiymatni va uni o'zgartiradigan funksiyani prop sifatida oladi.
Bu bir tomonlama oqimning amaliy ko'rinishi

4-bo'limda "ma'lumot yuqoridan pastga oqadi" degan edik. Bu yerda uning to'liq shakli ko'rinadi:

  • Ma'lumot pastga: soni={soni}.
  • Hodisa yuqoriga: oshir={oshir}.

Bola holatni o'zgartirmaydi - u faqat "menda nimadir bo'ldi" deb otaga xabar beradi. Qaror otada qabul qilinadi.

Shuning uchun React ilovasida ma'lumot qayerdan kelayotganini kuzatish oson: u doim yuqoridan tushadi.

Boshqariladigan bola #

JSX
import { useState } from "react";
import { chiz, yoz, matn } from "./dom-muhit.mjs";

function Qidiruv({ qiymat, ozgartir }) {
    return (
        <input
            value={qiymat}
            onChange={(h) => ozgartir(h.target.value)}
        />
    );
}

function Royxat({ so }) {
    const hammasi = ["Namangan", "Andijon", "Buxoro", "Nukus"];
    const topilgan = hammasi.filter((sh) =>
        sh.toLowerCase().includes(so.toLowerCase()));

    return <p id="natija">{topilgan.join(", ") || "topilmadi"}</p>;
}

function Sahifa() {
    const [so, ozgartir] = useState("");

    return (
        <div>
            <Qidiruv qiymat={so} ozgartir={ozgartir} />
            <Royxat so={so} />
            <p id="soni">Qidiruv: "{so}"</p>
        </div>
    );
}

await chiz(<Sahifa />);
console.log(matn("#natija"));

await yoz("input", "an");
console.log(matn("#natija"));
console.log(matn("#soni"));

await yoz("input", "xxx");
console.log(matn("#natija"));
Natija
Namangan, Andijon, Buxoro, Nukus
Namangan, Andijon
Qidiruv: "an"
topilmadi

Qidiruv va Royxat bir-birini bilmaydi. Ularni Sahifa bog'lab turadi.

Bu juda keng tarqalgan tuzilma: bitta ota, bir nechta bola va umumiy holat.

Yagona haqiqat manbai #

JSX
import { useState } from "react";
import { chiz, bos, matn } from "./dom-muhit.mjs";

function Yomon({ boshlangich }) {
    const [nusxa, ozgartir] = useState(boshlangich);
    return (
        <div>
            <p id="nusxa">Nusxa: {nusxa}</p>
            <p id="asl">Asl: {boshlangich}</p>
        </div>
    );
}

function Ota() {
    const [qiymat, ozgartir] = useState(1);

    return (
        <div>
            <button onClick={() => ozgartir(qiymat + 1)}>Oshirish</button>
            <Yomon boshlangich={qiymat} />
        </div>
    );
}

await chiz(<Ota />);
console.log(matn("#nusxa"), "|", matn("#asl"));

await bos("button");
console.log(matn("#nusxa"), "|", matn("#asl"));
Natija
Nusxa: 1 | Asl: 1
Nusxa: 1 | Asl: 2
Props ni holatga nusxalamang

useState(boshlangich) - boshlangich ni faqat birinchi chizishda oladi. Keyin prop o'zgarsa ham, holat eski qiymatda qolib ketadi.

Natijada ikki manba paydo bo'ladi va ular bir-biridan farq qiladi - yuqoridagi 1 va 2 kabi.

Bu yagona haqiqat manbai qoidasining buzilishi: har bir ma'lumot bitta joyda yashashi kerak.

Nima qilish kerak:

  1. Ko'pincha holat umuman kerak emas - props ni to'g'ridan-to'g'ri ishlating.
  2. Hisoblangan qiymat kerak bo'lsa, uni chizish paytida hisoblang: const ikki = qiymat * 2;.
  3. Haqiqatan mustaqil holat kerak bo'lsa (masalan, tahrirlash qoralamasi), buni ochiq qiling va nomida ko'rsating: qoralama, boshlangichQiymat.

Prop o'zgarganda holatni majburan yangilash kerak bo'lsa, komponentga key bering - shunda React uni butunlay qayta yaratadi.

key bilan qayta yaratish #

JSX
import { useState } from "react";
import { chiz, bos, yoz, matn } from "./dom-muhit.mjs";

function Tahrir({ boshlangich }) {
    const [matnQiymati, ozgartir] = useState(boshlangich);
    return (
        <input
            value={matnQiymati}
            onChange={(h) => ozgartir(h.target.value)}
        />
    );
}

function Sahifa() {
    const [tanlangan, tanla] = useState("Malika");

    return (
        <div>
            <button onClick={() => tanla("Nodira")}>Nodira ni tanlash</button>
            <Tahrir key={tanlangan} boshlangich={tanlangan} />
            <p id="tanlangan">Tanlangan: {tanlangan}</p>
        </div>
    );
}

const qiymat = () => document.querySelector("input").value;

await chiz(<Sahifa />);
console.log("boshida:", qiymat());

await yoz("input", "o'zgartirdim");
console.log("yozgandan keyin:", qiymat());

await bos("button");
console.log("boshqasini tanlagandan keyin:", qiymat());
console.log(matn("#tanlangan"));
Natija
boshida: Malika
yozgandan keyin: o'zgartirdim
boshqasini tanlagandan keyin: Nodira
Tanlangan: Nodira

key={tanlangan} o'zgarganda React eski komponentni butunlay tashlab, yangisini yaratadi - holat ham noldan boshlanadi.

Bu 5-bo'limdagi key ning boshqa tomoni: u nafaqat ro'yxatda, balki holatni qayta tiklashda ham ishlaydi.

Holatni qayerga qo'yish #

Holat eng yaqin umumiy otada Sahifa holat shu yerda Qidiruv Royxat qiymat + ozgartir so hodisa yuqoriga ma'lumot pastga Holatni faqat kerak bo'lgan joygacha ko'taring - hammasini eng yuqoriga yig'ish yomon fikr.
Hammasini eng yuqoriga ko'tarmang

Holatni ko'tarish foydali, lekin haddan oshirmang.

Har bir holatni eng yuqori komponentga yig'sangiz:

  1. Yuqoridagi komponent ulkan bo'lib ketadi;
  2. Har bir kichik o'zgarish butun daraxtni qayta chizadi;
  3. Props uzun zanjir bo'ylab pastga uzatiladi - bu "props burg'ulash" deb ataladi.

Qoida: holatni eng yaqin umumiy otagacha ko'taring, undan yuqoriga emas.

Faqat bitta komponentga tegishli holat (masalan, ochiq-yopiq menyu) o'sha komponentda qolsin.

Props zanjiri haqiqatan uzun bo'lsa, useContext (13-bo'lim) yordam beradi.

Amaliy topshiriq
  1. Ikki mustaqil holatli komponent yozing.
  2. Holatni otaga ko'tarib, ularni bog'lang.
  3. Bolaga o'zgartiruvchi funksiyani prop sifatida bering.
  4. Qidiruv maydoni va ro'yxatni bitta ota orqali bog'lang.
  5. Props ni holatga nusxalab, ular ajralib ketishini ko'ring.
  6. Nusxalashni olib tashlab, to'g'rilang.
  7. key bilan komponentni majburan qayta yarating.
  8. Faqat bitta komponentga kerak bo'lgan holatni pastda qoldiring.
  9. Props burg'ulash zanjirini yasab ko'ring.
  10. Holat qayerda turishi kerakligini har biri uchun ayting.

Xulosa #

  • Ikki komponent bir ma'lumotga muhtoj bo'lsa, holat umumiy otaga ko'chadi.
  • Bola qiymatni va o'zgartiruvchi funksiyani prop sifatida oladi.
  • Ma'lumot pastga, hodisa yuqoriga - bir tomonlama oqim.
  • Props ni holatga nusxalamang - ikki haqiqat manbai paydo bo'ladi.
  • Prop o'zgarganda holatni tiklash kerak bo'lsa - key bering.
  • Holatni eng yaqin umumiy otagacha ko'taring, undan yuqoriga emas.

Keyingi bo'limda useEffect ni 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.