9-bo‘lim
Holatni ko'tarish
Umumiy holatni ota-komponentga ko'chirish, bolaga funksiya uzatish, yagona haqiqat manbai va holatni qayerga qo'yish.
Ushbu bo‘lim mundarijasi
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:
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"));
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 #
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"));
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:
- Holat otaga ko'chdi.
- Bola qiymatni va uni o'zgartiradigan funksiyani prop sifatida oladi.
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 #
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"));
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 #
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"));
Nusxa: 1 | Asl: 1
Nusxa: 1 | Asl: 2
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:
- Ko'pincha holat umuman kerak emas - props ni to'g'ridan-to'g'ri ishlating.
- Hisoblangan qiymat kerak bo'lsa, uni chizish paytida
hisoblang:
const ikki = qiymat * 2;. - 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 #
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"));
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 #
Holatni ko'tarish foydali, lekin haddan oshirmang.
Har bir holatni eng yuqori komponentga yig'sangiz:
- Yuqoridagi komponent ulkan bo'lib ketadi;
- Har bir kichik o'zgarish butun daraxtni qayta chizadi;
- 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.
- Ikki mustaqil holatli komponent yozing.
- Holatni otaga ko'tarib, ularni bog'lang.
- Bolaga o'zgartiruvchi funksiyani prop sifatida bering.
- Qidiruv maydoni va ro'yxatni bitta ota orqali bog'lang.
- Props ni holatga nusxalab, ular ajralib ketishini ko'ring.
- Nusxalashni olib tashlab, to'g'rilang.
keybilan komponentni majburan qayta yarating.- Faqat bitta komponentga kerak bo'lgan holatni pastda qoldiring.
- Props burg'ulash zanjirini yasab ko'ring.
- 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 -
keybering. - Holatni eng yaqin umumiy otagacha ko'taring, undan yuqoriga emas.
Keyingi bo'limda useEffect 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.