8-bo‘lim

Formalar

Boshqariladigan maydonlar, bir nechta maydonni bitta holatda saqlash, tanlov va belgilash, tekshiruv va yuborish.

🕑 9 daqiqa o‘qish 📄 554 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Boshqariladigan maydon
  2. Bir nechta maydon
  3. Tanlash va belgilash
  4. Yuborish va tekshirish
  5. Boshqarilmaydigan maydon
  6. Xulosa

React da forma maydonlari odatda boshqariladigan bo'ladi: qiymat holatda saqlanadi, maydon esa uni ko'rsatadi.

Boshqariladigan maydon #

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

function Kirish() {
    const [ism, ozgartir] = useState("");

    return (
        <div>
            <input value={ism} onChange={(h) => ozgartir(h.target.value)} />
            <p id="aks">Yozilgan: {ism || "(bo'sh)"}</p>
            <p id="uzunlik">Uzunligi: {ism.length}</p>
        </div>
    );
}

await chiz(<Kirish />);
console.log(matn("#aks"), "|", matn("#uzunlik"));

await yoz("input", "Malika");
console.log(matn("#aks"), "|", matn("#uzunlik"));
Natija
Yozilgan: (bo'sh) | Uzunligi: 0
Yozilgan: Malika | Uzunligi: 6

Ikki qism birga ishlaydi:

  1. value={ism} - maydon holatdagi qiymatni ko'rsatadi.
  2. onChange - foydalanuvchi yozganda holatni yangilaydi.

Bu halqa "boshqariladigan komponent" deb ataladi.

value bering, lekin onChange ni unutmang

value berib, onChange yozmasangiz, maydon qotib qoladi: foydalanuvchi yozadi, lekin hech narsa o'zgarmaydi.

Sababi aniq: React maydon qiymati doim holatga teng bo'lishini ta'minlaydi. Holat o'zgarmasa, maydon ham o'zgarmaydi.

React bu holatda ogohlantirish beradi:

Natija
You provided a `value` prop to a form field without an
`onChange` handler.

Maydon haqiqatan o'zgarmas bo'lishi kerak bo'lsa, readOnly qo'shing. Boshlang'ich qiymat kerak bo'lsa-yu, keyinchalik boshqarish kerak bo'lmasa - defaultValue ishlating.

Bir nechta maydon #

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

function Forma() {
    const [malumot, ozgartir] = useState({ ism: "", email: "" });

    function maydonOzgardi(hodisa) {
        const { name, value } = hodisa.target;
        ozgartir((oldingi) => ({ ...oldingi, [name]: value }));
    }

    return (
        <form>
            <input name="ism" value={malumot.ism} onChange={maydonOzgardi} />
            <input
                name="email"
                type="email"
                value={malumot.email}
                onChange={maydonOzgardi}
            />
            <p id="aks">
                {malumot.ism || "(bo'sh)"} / {malumot.email || "(bo'sh)"}
            </p>
        </form>
    );
}

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

await yoz("input[name=ism]", "Nodira");
await yoz("input[name=email]", "[email protected]");
console.log(matn("#aks"));
Natija
(bo'sh) / (bo'sh)
Nodira / [email protected]

Bitta ishlovchi hamma maydonga xizmat qiladi.

Kalit - [name]: value yozuvi: kvadrat qavs obyektda hisoblab topiladigan kalit yaratadi, ya'ni maydonning name atributi holatdagi xossa nomiga aylanadi.

Har bir maydonga alohida holat kerakmi

Ikki yondashuv ham to'g'ri:

JSX
const [ism, ismniOzgartir] = useState("");
const [email, emailniOzgartir] = useState("");

const [malumot, ozgartir] = useState({ ism: "", email: "" });

Alohida holat - ikki-uch maydon uchun soddaroq va o'qishli.

Bitta obyekt - maydon ko'p bo'lganda qulayroq: yuqoridagi kabi bitta ishlovchi yetadi va butun forma qiymatini bir joyda uzatish oson.

Beshta maydondan oshsa, odatda obyekt afzal.

Tanlash va belgilash #

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

function Sozlamalar() {
    const [guruh, guruhniOzgartir] = useState("A1");
    const [rozi, roziniOzgartir] = useState(false);

    return (
        <div>
            <select
                value={guruh}
                onChange={(h) => guruhniOzgartir(h.target.value)}
            >
                <option value="A1">A1</option>
                <option value="B2">B2</option>
            </select>
            <input
                id="rozi"
                type="checkbox"
                checked={rozi}
                onChange={(h) => roziniOzgartir(h.target.checked)}
            />
            <p id="aks">Guruh: {guruh}, rozi: {rozi ? "ha" : "yo'q"}</p>
        </div>
    );
}

await chiz(<Sozlamalar />);
console.log(matn("#aks"));

await bos("#rozi");
console.log(matn("#aks"));
Natija
Guruh: A1, rozi: yo'q
Guruh: A1, rozi: ha
ElementQiymat qayerdan
<input type="text">h.target.value
<input type="checkbox">h.target.checked
<select>h.target.value
select React da soddaroq

Toza HTML da tanlangan variantni belgilash uchun <option> ga selected atributi qo'yilardi.

React da esa value <select> ning o'zida turadi - bu ancha qulay, chunki tanlangan qiymat bitta joyda.

<textarea> ham shunday: HTML da matn teglar orasiga yozilardi, React da esa value prop sifatida beriladi.

Yuborish va tekshirish #

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

function tekshir({ ism, yosh }) {
    const xatolar = {};
    if (ism.trim().length < 2) xatolar.ism = "ism juda qisqa";
    const son = Number(yosh);
    if (!Number.isInteger(son) || son < 1 || son > 120) {
        xatolar.yosh = "yosh 1 va 120 orasida bo'lsin";
    }
    return xatolar;
}

function Forma() {
    const [malumot, ozgartir] = useState({ ism: "", yosh: "" });
    const [xatolar, xatolarniOzgartir] = useState({});
    const [natija, natijaniOzgartir] = useState("hali yuborilmadi");

    function maydon(hodisa) {
        const { name, value } = hodisa.target;
        ozgartir((oldingi) => ({ ...oldingi, [name]: value }));
    }

    function yuborildi(hodisa) {
        hodisa.preventDefault();
        const topilgan = tekshir(malumot);
        xatolarniOzgartir(topilgan);

        if (Object.keys(topilgan).length === 0) {
            natijaniOzgartir(`qabul qilindi: ${malumot.ism}`);
        } else {
            natijaniOzgartir("tekshiruvdan o'tmadi");
        }
    }

    return (
        <form onSubmit={yuborildi}>
            <input name="ism" value={malumot.ism} onChange={maydon} />
            <input name="yosh" value={malumot.yosh} onChange={maydon} />
            <button type="submit">Yuborish</button>
            <p id="xato">
                {Object.values(xatolar).join("; ") || "xato yo'q"}
            </p>
            <p id="natija">{natija}</p>
        </form>
    );
}

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

await bos("button");
console.log("bo'sh forma:", matn("#xato"));

await yoz("input[name=ism]", "M");
await yoz("input[name=yosh]", "200");
await bos("button");
console.log("noto'g'ri:", matn("#xato"));

await yoz("input[name=ism]", "Malika");
await yoz("input[name=yosh]", "20");
await bos("button");
console.log("to'g'ri:", matn("#natija"));
Natija
hali yuborilmadi
bo'sh forma: ism juda qisqa; yosh 1 va 120 orasida bo'lsin
noto'g'ri: ism juda qisqa; yosh 1 va 120 orasida bo'lsin
to'g'ri: qabul qilindi: Malika

Tekshiruv funksiyasi komponentdan tashqarida yozilgan - shunda uni alohida sinash mumkin (19-bo'lim).

Brauzer tekshiruvi yetarli emas

HTML ning required, minLength, type="email" atributlari foydali: ular tez javob beradi va qo'shimcha kod talab qilmaydi.

Lekin ularga tayanib bo'lmaydi. Ularni brauzerda o'chirib qo'yish yoki so'rovni to'g'ridan-to'g'ri yuborish mumkin.

Shuning uchun tekshiruv uch joyda bo'ladi:

  1. Brauzerda - foydalanuvchiga tez javob uchun;
  2. Mijoz kodida - aniqroq xabar va murakkabroq qoidalar uchun;
  3. Serverda - majburiy, chunki faqat shu ishonchli.

Node.js darsligining 14-bo'limida serverdagi tekshiruvni ko'rgansiz. Mijozdagi tekshiruv uni almashtirmaydi.

Boshqarilmaydigan maydon #

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

function Boshqarilmaydigan() {
    const maydon = useRef(null);
    const [natija, ozgartir] = useState("");

    function yuborildi(hodisa) {
        hodisa.preventDefault();
        ozgartir(maydon.current.value);
    }

    return (
        <form onSubmit={yuborildi}>
            <input ref={maydon} defaultValue="boshlang'ich" />
            <button type="submit">O'qish</button>
            <p id="natija">{natija || "(hali o'qilmadi)"}</p>
        </form>
    );
}

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

await yoz("input", "yangi matn");
console.log("yozgandan keyin:", matn("#natija"));

await bos("button");
console.log("o'qigandan keyin:", matn("#natija"));
Natija
(hali o'qilmadi)
yozgandan keyin: (hali o'qilmadi)
o'qigandan keyin: yangi matn

Bu yerda qiymat holatda saqlanmaydi - u DOM da yashaydi va faqat kerak bo'lganda o'qiladi.

E'tibor bering: yozish paytida ekranda hech narsa o'zgarmadi, chunki React qiymatni kuzatmayapti.

YondashuvQachon
BoshqariladiganDeyarli har doim
BoshqarilmaydiganFayl tanlash, uchinchi tomon kutubxonalari

useRef ni 12-bo'limda batafsil ko'ramiz.

Amaliy topshiriq
  1. Boshqariladigan matn maydonini yozing.
  2. onChange ni olib tashlab, maydon qotib qolishini ko'ring.
  3. Ikki maydonni bitta obyekt holatida saqlang.
  4. [name]: value yozuvi bilan bitta ishlovchi yozing.
  5. checkbox ni checked bilan boshqaring.
  6. <select> ga value berib, tanlovni boshqaring.
  7. onSubmit da preventDefault() ishlating.
  8. Tekshiruv funksiyasini komponentdan tashqariga chiqaring.
  9. Xatolarni maydon nomi bilan ko'rsating.
  10. useRef bilan boshqarilmaydigan maydon yozing.

Xulosa #

  • Boshqariladigan maydon: value + onChange juftligi.
  • value berib onChange yozmasangiz, maydon qotib qoladi.
  • Ko'p maydon uchun bitta obyekt holat va [name]: value yozuvi.
  • checkbox dan qiymat checked orqali olinadi.
  • React da <select> va <textarea> qiymati prop sifatida beriladi.
  • Tekshiruv funksiyasini komponentdan tashqarida yozing.
  • Mijozdagi tekshiruv serverdagisini almashtirmaydi.
  • Boshqarilmaydigan maydon - kam holat uchun; qiymat DOM da qoladi.

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