15-bo‘lim

O'z ilgaklaringiz

Ilgaklar qoidalari, takrorlanuvchi mantiqni ilgakka ajratish, holat ulashilmasligi va foydali ilgaklar to'plami.

🕑 8 daqiqa o‘qish 📄 505 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Ilgaklar qoidalari
  2. Takrorlanuvchi mantiq
  3. Ma'lumot oluvchi ilgak
  4. Qiymat o'zgarishini kechiktirish
  5. Foydali ilgaklar
  6. Xulosa

Ilgak (hook) - nomi use bilan boshlanadigan funksiya. U boshqa ilgaklarni chaqira oladi.

O'z ilgagingizni yozish - React dagi qayta ishlatishning asosiy usuli.

Ilgaklar qoidalari #

Ikki qoida - ularni buzib bo'lmaydi

1. Ilgaklarni faqat eng yuqori darajada chaqiring.

Shart, sikl yoki ichma-ich funksiya ichida emas:

JSX
if (shart) {
    const [x, y] = useState(0);      // XATO
}

for (const a of royxat) {
    useEffect(...);                   // XATO
}

2. Ilgaklarni faqat React funksiyalaridan chaqiring.

Komponentdan yoki boshqa ilgakdan - oddiy funksiyadan emas.

Nima uchun. React ilgaklarni nom bilan emas, tartib raqami bilan eslab qoladi: birinchi useState, ikkinchi useState va hokazo.

Shart ichida bo'lsa, tartib chizishdan chizishga o'zgaradi va React qiymatlarni aralashtirib yuboradi: bir chizishda birinchi holat, keyingisida boshqasi.

Shuning uchun qoida qat'iy. eslint-plugin-react-hooks uni avtomatik tekshiradi - uni albatta o'rnating.

Shart kerak bo'lsa, uni ilgak ichiga qo'ying:

JSX
useEffect(() => {
    if (!shart) return;
    // ...
}, [shart]);

Takrorlanuvchi mantiq #

Ikki komponentda bir xil kod bo'lsa, u ilgakka ajratiladi:

JSX
import { useState, useCallback } from "react";

export function useAlmashtirgich(boshlangich = false) {
    const [ochiq, ozgartir] = useState(boshlangich);

    const almashtir = useCallback(() => ozgartir((o) => !o), []);
    const yop = useCallback(() => ozgartir(false), []);
    const och = useCallback(() => ozgartir(true), []);

    return { ochiq, almashtir, yop, och };
}
JSX
import { useAlmashtirgich } from "./use-almashtirgich.mjs";
import { chiz, bos, matn } from "./dom-muhit.mjs";

function Menyu() {
    const { ochiq, almashtir } = useAlmashtirgich();
    return (
        <div>
            <button id="menyu" onClick={almashtir}>Menyu</button>
            <p id="menyu-holat">{ochiq ? "ochiq" : "yopiq"}</p>
        </div>
    );
}

function Oyna() {
    const { ochiq, och, yop } = useAlmashtirgich(true);
    return (
        <div>
            <button id="och" onClick={och}>Ochish</button>
            <button id="yop" onClick={yop}>Yopish</button>
            <p id="oyna-holat">{ochiq ? "ochiq" : "yopiq"}</p>
        </div>
    );
}

await chiz(<div><Menyu /><Oyna /></div>);
console.log("menyu:", matn("#menyu-holat"), "| oyna:", matn("#oyna-holat"));

await bos("#menyu");
console.log("menyu bosildi:", matn("#menyu-holat"),
    "| oyna:", matn("#oyna-holat"));

await bos("#yop");
console.log("oyna yopildi:", matn("#menyu-holat"),
    "| oyna:", matn("#oyna-holat"));
Natija
menyu: yopiq | oyna: ochiq
menyu bosildi: ochiq | oyna: ochiq
oyna yopildi: ochiq | oyna: yopiq

Ikki komponent bir xil ilgakni ishlatadi, lekin ularning holati mutlaqo mustaqil.

Ilgak mantiqni ulashadi, holatni emas

Bu eng ko'p chalkashtiriladigan nuqta.

useAlmashtirgich chaqirilgan har bir joyda yangi useState yaratiladi. Ya'ni ilgak - bu retsept, umumiy ombor emas.

Yuqorida buni ko'rdik: menyu ochilganda oyna o'zgarmadi.

Holat haqiqatan ulashilishi kerak bo'lsa, uni yuqoriga ko'tarish (9-bo'lim) yoki kontekstga qo'yish (13-bo'lim) kerak.

Ma'lumot oluvchi ilgak #

JSX
import { useState, useEffect } from "react";

export function useSorov(manzil) {
    const [holat, ozgartir] = useState({
        malumot: null,
        yuklanmoqda: true,
        xato: null,
    });

    useEffect(() => {
        let bekor = false;
        ozgartir({ malumot: null, yuklanmoqda: true, xato: null });

        fetch(manzil)
            .then((javob) => {
                if (!javob.ok) throw new Error(`holat ${javob.status}`);
                return javob.json();
            })
            .then((malumot) => {
                if (!bekor) {
                    ozgartir({
                        malumot,
                        yuklanmoqda: false,
                        xato: null,
                    });
                }
            })
            .catch((x) => {
                if (!bekor) {
                    ozgartir({ malumot: null, yuklanmoqda: false,
                        xato: x.message });
                }
            });

        return () => { bekor = true; };
    }, [manzil]);

    return holat;
}
JSX
import { createServer } from "node:http";
import { useSorov } from "./use-sorov.mjs";
import { chiz, kut, matn } from "./dom-muhit.mjs";

const server = createServer((sorov, javob) => {
    if (sorov.url === "/yoq") {
        javob.writeHead(404).end("{}");
        return;
    }
    javob.writeHead(200, { "Content-Type": "application/json" });
    javob.end(JSON.stringify({ ism: "Malika" }));
});
server.listen(0);
const asos = `http://localhost:${server.address().port}`;

function Profil({ manzil }) {
    const { malumot, yuklanmoqda, xato } = useSorov(manzil);

    if (yuklanmoqda) return <p id="holat">yuklanmoqda</p>;
    if (xato) return <p id="holat">xato: {xato}</p>;
    return <p id="holat">salom, {malumot.ism}</p>;
}

await chiz(<Profil manzil={`${asos}/bor`} />);
console.log(matn("#holat"));

await kut();
console.log(matn("#holat"));

await chiz(<Profil key="2" manzil={`${asos}/yoq`} />);
await kut();
console.log(matn("#holat"));

server.close();
Natija
yuklanmoqda
salom, Malika
xato: holat 404

11-bo'limdagi butun mantiq endi bitta qatorga sig'di:

JSX
const { malumot, yuklanmoqda, xato } = useSorov(manzil);

Har bir komponentda uchta useState va bitta useEffect yozish kerak emas.

Qiymat o'zgarishini kechiktirish #

JSX
import { useState, useEffect } from "react";

export function useKechiktir(qiymat, kechikish = 300) {
    const [kechikkan, ozgartir] = useState(qiymat);

    useEffect(() => {
        const id = setTimeout(() => ozgartir(qiymat), kechikish);
        return () => clearTimeout(id);
    }, [qiymat, kechikish]);

    return kechikkan;
}
JSX
import { useState } from "react";
import { useKechiktir } from "./use-kechiktir.mjs";
import { chiz, yoz, kut, matn } from "./dom-muhit.mjs";

const sorovlar = [];

function Qidiruv() {
    const [so, ozgartir] = useState("");
    const kechikkan = useKechiktir(so, 50);

    if (kechikkan !== "") sorovlar.push(kechikkan);

    return (
        <div>
            <input value={so} onChange={(h) => ozgartir(h.target.value)} />
            <p id="holat">yozilgan: "{so}", so'rov: "{kechikkan}"</p>
        </div>
    );
}

await chiz(<Qidiruv />);

await yoz("input", "r");
await yoz("input", "re");
await yoz("input", "rea");
console.log("tez yozilganda:", matn("#holat"));

await kut(120);
console.log("kutilgandan keyin:", matn("#holat"));
console.log("yuborilgan so'rovlar:", sorovlar.join(", "));
Natija
tez yozilganda: yozilgan: "rea", so'rov: ""
kutilgandan keyin: yozilgan: "rea", so'rov: "rea"
yuborilgan so'rovlar: rea

Uch marta yozildi, lekin so'rov bittagina bo'ldi.

useKechiktir foydalanuvchi to'xtaguncha kutadi - qidiruv maydonlarida bu server yukini sezilarli kamaytiradi.

Tozalovchi funksiya eski taymerni bekor qiladi (10-bo'lim), shu sababdan oraliq qiymatlar umuman o'tmaydi.

Foydali ilgaklar #

IlgakNima qiladi
useAlmashtirgichOchiq/yopiq holat
useSorovMa'lumot olish
useKechiktirTez o'zgarishni kechiktirish
useMahalliySaqlashBrauzer xotirasiga saqlash
useOldingiOldingi qiymatni eslash (12-bo'lim)
Ilgak qachon yozish kerak

Uch belgi:

  1. Takrorlanish - bir xil useState + useEffect juftligi ikki joyda uchrasa.
  2. Nom topilsa - mantiqqa yaxshi nom bera olsangiz, u mustaqil tushuncha.
  3. Sinash kerak bo'lsa - ilgakni alohida sinash komponentni sinashdan osonroq.

Teskarisi ham to'g'ri: bitta joyda ishlatiladigan uch qatorlik mantiqni ilgakka chiqarish foyda bermaydi - u faqat kodni ikki faylga bo'ladi.

Va yodda tuting: ilgak nomi use bilan boshlanishi shart. Aks holda eslint uni ilgak deb tanimaydi va qoidalarni tekshirmaydi.

Amaliy topshiriq
  1. useState ni shart ichiga qo'yib, xatoni ko'ring.
  2. useAlmashtirgich ilgagini yozing.
  3. Uni ikki komponentda ishlatib, holat mustaqilligini isbotlang.
  4. Ma'lumot oluvchi ilgak yozing.
  5. Uni ikki xil manzil bilan ishlating.
  6. Kechiktiruvchi ilgak yozing.
  7. Tez yozib, so'rovlar soni kamayganini ko'ring.
  8. Tozalovchini olib tashlab, farqni ko'ring.
  9. Nomi use bilan boshlanmaydigan ilgak yozib ko'ring.
  10. Bitta joyda ishlatiladigan mantiqni ilgakka chiqarmang.

Xulosa #

  • Ilgak - nomi use bilan boshlanadigan funksiya.
  • Ikki qoida: faqat eng yuqori darajada va faqat React funksiyalaridan.
  • Sabab - React ilgaklarni tartib bo'yicha eslab qoladi.
  • Ilgak mantiqni ulashadi, holatni emas - har chaqiruv o'z holatini oladi.
  • Takrorlanuvchi useState + useEffect juftligi - ilgakka ajratish belgisi.
  • Bitta joyda ishlatiladigan qisqa mantiqni ajratmang.

Keyingi bo'limda kompozitsiya naqshlarini 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.