6-bo‘lim

Hodisalar

onClick va boshqa ishlovchilar, hodisa obyekti, argument uzatish, preventDefault, ko'tarilish va ishlovchini to'g'ri yozish.

🕑 11 daqiqa o‘qish 📄 599 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Birinchi ishlovchi
  2. Argument uzatish
  3. Hodisa obyekti
  4. preventDefault
  5. Ko'tarilish
  6. Ko'p ishlatiladigan hodisalar
  7. Xulosa

React da hodisa ishlovchisi prop sifatida beriladi: onClick, onChange, onSubmit.

Birinchi ishlovchi #

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

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

    function bosildi() {
        ozgartir(soni + 1);
    }

    return <button onClick={bosildi}>Bosildi: {soni}</button>;
}

await chiz(<Tugma />);
console.log(matn("button"));

await bos("button");
console.log(matn("button"));

await bos("button");
console.log(matn("button"));
Natija
Bosildi: 0
Bosildi: 1
Bosildi: 2

onClick ga funksiyaning o'zi beriladi, uning natijasi emas.

Qavs qo'yish - eng ko'p uchraydigan xato

Farqni yaxshi tushunib oling:

JSX
<button onClick={bosildi}>     // to'g'ri: funksiya beriladi
<button onClick={bosildi()}>   // XATO: funksiya darhol chaqiriladi

Ikkinchi shaklda bosildi() chizish paytida ishlaydi va uning natijasi (odatda undefined) onClick ga beriladi.

Oqibati: tugmani bosganda hech narsa bo'lmaydi, lekin sahifa ochilishi bilan funksiya bir marta ishlaydi.

Agar u holatni o'zgartirsa, cheksiz sikl boshlanadi: chizish → holat o'zgarishi → qayta chizish → yana chaqiruv. React shunda xato beradi:

Natija
Too many re-renders

Argument kerak bo'lsa, funksiyani o'rab bering - buni quyida ko'ramiz.

Argument uzatish #

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

function Baholash() {
    const [ball, ozgartir] = useState(50);

    return (
        <div>
            <p id="natija">Ball: {ball}</p>
            <button id="kam" onClick={() => ozgartir(ball - 10)}>-10</button>
            <button id="kop" onClick={() => ozgartir(ball + 10)}>+10</button>
        </div>
    );
}

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

await bos("#kop");
console.log(matn("#natija"));

await bos("#kam");
await bos("#kam");
console.log(matn("#natija"));
Natija
Ball: 50
Ball: 60
Ball: 40

() => ozgartir(ball + 10) - o'rovchi funksiya. U bosilganda chaqiriladi va ichidagi kodni bajaradi.

Bu "qavs qo'yish" muammosining yechimi: tashqi funksiya darhol yaratiladi, lekin ichkarisi faqat bosilganda ishlaydi.

Hodisa obyekti #

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

function Korish() {
    function bosildi(hodisa) {
        console.log("turi:", hodisa.type);
        console.log("teg:", hodisa.target.tagName);
        console.log("id:", hodisa.target.id);
        console.log("ko'tariladi:", hodisa.bubbles);
    }

    return <button id="tugma" onClick={bosildi}>Bos</button>;
}

await chiz(<Korish />);
await bos("#tugma");
Natija
turi: click
teg: BUTTON
id: tugma
ko'tariladi: true

Ishlovchi birinchi argument sifatida hodisa obyektini oladi.

XossaNima beradi
typeHodisa turi
targetHodisa kelib chiqqan element
currentTargetIshlovchi qo'yilgan element
preventDefault()Odatiy xatti-harakatni bekor qiladi
stopPropagation()Ko'tarilishni to'xtatadi

preventDefault #

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

function Forma() {
    const [holat, ozgartir] = useState("kutilmoqda");

    function yuborildi(hodisa) {
        hodisa.preventDefault();
        ozgartir("yuborildi, sahifa yangilanmadi");
    }

    return (
        <form onSubmit={yuborildi}>
            <button type="submit">Yuborish</button>
            <p id="holat">{holat}</p>
        </form>
    );
}

await chiz(<Forma />);
console.log(matn("#holat"));

await bos("button");
console.log(matn("#holat"));
Natija
kutilmoqda
yuborildi, sahifa yangilanmadi

Forma odatda yuborilganda sahifani qayta yuklaydi - bu HTML ning eski xatti-harakati.

React ilovasida bu deyarli hech qachon kerak emas: preventDefault() uni to'xtatadi.

onSubmit ni formaga qo'ying, tugmaga emas

Ishlovchini <form> ga qo'yish kerak, <button> ga emas:

JSX
<form onSubmit={yuborildi}>      // to'g'ri
<button onClick={yuborildi}>     // to'liq emas

Sabab: foydalanuvchi formani Enter bosib ham yuborishi mumkin. Bu holda tugma bosilmaydi, lekin submit hodisasi baribir sodir bo'ladi.

onSubmit ikkala yo'lni ham qamrab oladi va klaviatura bilan ishlaydiganlar uchun muhim.

Ko'tarilish #

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

function Ichma() {
    const izlar = [];

    function tashqi() {
        izlar.push("tashqi");
        console.log(izlar.join(" -> "));
    }

    function ichki(hodisa) {
        izlar.push("ichki");
    }

    function toxtatuvchi(hodisa) {
        hodisa.stopPropagation();
        console.log("faqat ichki (to'xtatildi)");
    }

    return (
        <div onClick={tashqi}>
            <button id="oddiy" onClick={ichki}>Oddiy</button>
            <button id="toxta" onClick={toxtatuvchi}>To'xtatuvchi</button>
        </div>
    );
}

await chiz(<Ichma />);
await bos("#oddiy");
await bos("#toxta");
Natija
ichki -> tashqi
faqat ichki (to'xtatildi)

Hodisa ichkaridan tashqariga ko'tariladi: avval tugmaning ishlovchisi, keyin uni o'rab turgan <div> niki.

stopPropagation() bu zanjirni to'xtatadi.

stopPropagation ni kam ishlating

U muammoni hal qilganday tuyuladi, lekin ko'pincha yangisini yaratadi: tashqaridagi kod hodisani umuman ko'rmaydi.

Masalan, "sahifaning istalgan joyiga bosilsa, menyuni yop" degan mantiq buzilib qoladi va sababi darhol ko'rinmaydi.

Ko'pincha yaxshiroq yechim - tashqi ishlovchida tekshirish:

JSX
function tashqi(hodisa) {
    if (hodisa.target.closest(".ichki")) return;
    // ...
}

Shunda hodisa o'z yo'lida davom etadi, siz esa faqat kerakli holatda ish qilasiz.

Ko'p ishlatiladigan hodisalar #

PropQachon
onClickBosilganda
onChangeKiritish o'zgarganda
onSubmitForma yuborilganda
onKeyDownKlavisha bosilganda
onFocus / onBlurFokus kelganda / ketganda
onMouseEnter / onMouseLeaveSichqoncha ustiga kelganda
JSX
import { useState } from "react";
import { chiz, yoz, matn } from "./dom-muhit.mjs";

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

    return (
        <div>
            <input value={so} onChange={(h) => ozgartir(h.target.value)} />
            <p id="natija">
                {so === "" ? "hech narsa yozilmadi" : `qidirilmoqda: ${so}`}
            </p>
        </div>
    );
}

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

await yoz("input", "react");
console.log(matn("#natija"));
Natija
hech narsa yozilmadi
qidirilmoqda: react

onChange React da har bir belgida ishlaydi - HTML dagi change dan farqli o'laroq, u fokus ketishini kutmaydi.

React hodisalari - sintetik

React har bir element uchun alohida tinglovchi qo'ymaydi. U hodisalarni ildizda tinglaydi va keyin to'g'ri komponentga yo'naltiradi.

Sizga beriladigan hodisa obyekti ham brauzerning asl obyekti emas, balki React ning sintetik o'ramasi. U hamma brauzerda bir xil ishlaydi - eski davrda bu katta muammo edi.

Asl brauzer hodisasi kerak bo'lsa, u hodisa.nativeEvent da turadi. Amalda bu juda kam kerak bo'ladi.

Amaliy topshiriq
  1. onClick bilan hisoblagich yozing.
  2. onClick={bosildi()} deb yozib, nima bo'lishini ko'ring.
  3. O'rovchi funksiya bilan argument uzating.
  4. Hodisa obyektidan type va target ni chiqaring.
  5. Formada preventDefault() ishlating.
  6. Ishlovchini tugmaga qo'yib, Enter bilan sinab ko'ring.
  7. Ichma-ich ishlovchilar bilan ko'tarilishni kuzating.
  8. stopPropagation() qo'shib, farqni ko'ring.
  9. onChange bilan kiritishni holatga bog'lang.
  10. onMouseEnter bilan ustiga kelishni ushlang.

Xulosa #

  • Ishlovchi prop sifatida beriladi: onClick={funksiya}.
  • Qavs qo'ymang: onClick={f()} funksiyani darhol chaqiradi.
  • Argument kerak bo'lsa - o'rovchi funksiya: onClick={() => f(x)}.
  • Ishlovchi hodisa obyektini oladi; target - hodisa kelib chiqqan element.
  • Formada preventDefault() sahifa yangilanishini to'xtatadi.
  • onSubmit ni formaga qo'ying - Enter bilan ham ishlaydi.
  • Hodisa ichkaridan tashqariga ko'tariladi; stopPropagation ni kam ishlating.
  • React hodisalari sintetik - hamma brauzerda bir xil.

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