State va useState
Props โ o'zgarmas ma'lumot edi. Lekin real ilovalarda ma'lumot doimo o'zgaradi: foydalanuvchi tugmani bosadi, formaga yozadi, ro'yxatga element qo'shadi. Vaqt o'tishi bilan o'zgaradigan ma'lumotni React'da state (holat) boshqaradi. Ushbu dars โ React'ning yuragi.
State (holat) nima?
State โ bu komponentning "xotirasi". Bu โ vaqt o'tishi bilan o'zgaradigan va shu o'zgarish ekranda aks etishi kerak bo'lgan ma'lumot. Masalan:
- Hisoblagichning joriy qiymati;
- Formadagi matn maydoniga foydalanuvchi yozgan matn;
- Modal oyna ochiqmi yoki yopiqmi;
- Serverdan yuklangan foydalanuvchilar ro'yxati.
Muhim savol: nega oddiy o'zgaruvchi ishlatmaymiz? Chunki oddiy o'zgaruvchini o'zgartirsak, React bundan xabar topmaydi va ekranni yangilamaydi. Quyidagi kod ishlamaydi:
function Hisoblagich() {
let count = 0; // oddiy o'zgaruvchi
function bosildi() {
count = count + 1;
console.log(count); // konsolda oshadi...
// ...lekin ekranda O'ZGARMAYDI!
}
return <button onClick={bosildi}>{count}</button>;
}
Bu yerda count konsolda oshsa-da, ekran yangilanmaydi. Sababi: React ekranni faqat maxsus signal olganda qayta chizadi. Ana shu signalni state beradi.
useState hook
State bilan ishlash uchun React useState nomli hookdan foydalanadi. Hook โ bu use so'zi bilan boshlanadigan maxsus funksiya bo'lib, komponentga React imkoniyatlarini "ulaydi". Avval uni import qilamiz:
import { useState } from "react";
useState boshlang'ich qiymatni argument sifatida oladi va ikki elementli massiv qaytaradi: joriy qiymat va uni o'zgartiruvchi funksiya. Bu massivni destructuring bilan olamiz:
const [count, setCount] = useState(0);
Bu qatorni tahlil qilamiz:
countโ holatning joriy qiymati (boshida0);setCountโ holatni yangilovchi funksiya (odat bo'yichaset+ holat nomi);useState(0)โ0โ bu boshlang'ich qiymat.
useState) faqat komponentning eng yuqori darajasida chaqirilishi kerak. Ularni if, for yoki oddiy funksiyalar ichida chaqirmang.Holatni yangilash va re-render
Holatni to'g'ridan-to'g'ri o'zgartirmaymiz. Uning o'rniga yangilovchi funksiyani (setCount) chaqiramiz. Bu funksiya ikki ish qiladi:
- Holatning yangi qiymatini saqlaydi;
- Komponentni qayta render qiladi (re-render) โ ya'ni komponent funksiyasi qaytadan ishga tushib, ekran yangilanadi.
Mana to'g'ri ishlaydigan hisoblagich:
import { useState } from "react";
function Hisoblagich() {
const [count, setCount] = useState(0);
function bosildi() {
setCount(count + 1); // holatni yangilaymiz
}
return <button onClick={bosildi}>Bosildi: {count}</button>;
}
Endi tugma bosilganda: setCount yangi qiymatni saqlaydi va React komponentni qaytadan chizadi. Yangi count qiymati ekranda ko'rinadi. Aynan shu โ React'ning deklarativ ishlash mexanizmi.
count = count + 1 yoki count++ ishlamaydi va xato hisoblanadi. Har doim setCount(...) orqali yangilang.Hodisalarni qayta ishlash (event handling)
React'da hodisalar (events) JSX atributlari orqali biriktiriladi. Ular camelCaseda yoziladi va qiymat sifatida funksiyani qabul qiladi:
onClickโ bosilganda;onChangeโ qiymat o'zgarganda (input uchun);onSubmitโ forma yuborilganda;onMouseEnter,onKeyDownva boshqalar.
Muhim nozik jihat: funksiyani chaqirmasdan uzatamiz โ nomini { } ichida beramiz:
// TO'G'RI โ funksiyaning o'zini beramiz
<button onClick={bosildi}>Bosing</button>
// XATO โ funksiyani darrov chaqirib yuboramiz
<button onClick={bosildi()}>Bosing</button>
Ikkinchi holatda bosildi() render paytida darhol chaqiriladi โ bu noto'g'ri. Agar funksiyaga argument uzatish kerak bo'lsa, uni ochilgan strelka funksiya ichiga o'raymiz:
<button onClick={() => setCount(count + 1)}>+1</button>
<button onClick={() => setCount(0)}>Tozalash</button>
onClick={(e) => console.log(e)}. Undan, masalan, input qiymatini olishda foydalanamiz (keyingi darsda ko'ramiz).To'liq hisoblagich misoli
Endi bir necha tugmali to'liq hisoblagichni yig'amiz โ oshirish, kamaytirish va tozalash:
import { useState } from "react";
function Hisoblagich() {
const [count, setCount] = useState(0);
return (
<div>
<h2>Qiymat: {count}</h2>
<button onClick={() => setCount(count + 1)}>+1</button>
<button onClick={() => setCount(count - 1)}>-1</button>
<button onClick={() => setCount(0)}>Tozalash</button>
</div>
);
}
export default Hisoblagich;
Bu komponent to'liq ishlaydi: har bir tugma setCountni chaqiradi, React qayta render qiladi va yangi qiymat <h2>da ko'rinadi.
Oldingi holatga asoslanib yangilash
Agar yangi qiymat eski qiymatga bog'liq bo'lsa (masalan, oshirish), setCountga qiymat o'rniga funksiya berish xavfsizroq. React bu funksiyaga eng so'nggi holatni uzatadi:
// Yaxshiroq usul:
setCount(prev => prev + 1);
// Bir necha marta chaqirsangiz farqi bilinadi:
function ucchiOshir() {
setCount(prev => prev + 1);
setCount(prev => prev + 1);
setCount(prev => prev + 1);
// count 3 ga oshadi (to'g'ri)
}
Agar setCount(count + 1) ni uch marta yozsangiz, natija kutilganidek bo'lmaydi โ chunki count bitta render davomida o'zgarmaydi. Funksiya shaklida (prev => prev + 1) esa har safar eng so'nggi qiymat olinadi.
setCount holatni darhol o'zgartirmaydi. React yangilanishlarni to'plab, so'ng bir marta qayta render qiladi (batching). Shuning uchun yangilashdan keyin darrov countni o'qisangiz, eski qiymatni ko'rasiz.Xulosa
- State โ komponentning vaqt o'tishi bilan o'zgaradigan xotirasi; oddiy o'zgaruvchi bu vazifani bajara olmaydi;
useStatehook joriy qiymat va yangilovchi funksiyani qaytaradi:const [x, setX] = useState(boshlang'ich);- Holatni faqat set-funksiya orqali yangilaymiz โ to'g'ridan-to'g'ri o'zgartirmaymiz;
- Holat o'zgarganda React komponentni qayta render qiladi va ekran yangilanadi;
- Hodisalar camelCaseda (
onClick) yoziladi va funksiya qabul qiladi โ uni chaqirmang, uzating; - Eski holatga bog'liq yangilashda funksiya shaklidan foydalaning:
setX(prev => prev + 1).