Mundarija (27)
- Bu darsda
- 1. Nega bu kerak?
- 2. Class komponent anatomiyasi
- 2.1 Bir xil komponent — ikki yozuvda
- 2.2 setState birlashtiradi
- 3. this tuzog'i
- 3.1 Metod uzatilganda
- 3.2 Uch davo — eski kodda uchalasi ham uchraydi
- 4. Lifecycle metodlari
- 4.1 Uch asosiy metod
- 4.2 Bitta effekt — uch metodga bo'lingan
- 4.3 To'liq moslik jadvali
- 5. PureComponent
- 6. Class'ni hooklarga ko'chirish
- 6.1 Qadamlar
- 6.2 Misol: oshxona taymeri
- 6.3 Qachon ko'chirish kerak emas
- 7. Vazifalar qadami: XatoChegarasi ni o'qish
- 8. Ko'p uchraydigan xatolar
- 9. Mashqlar
- 1-mashq (oson): moslik
- 2-mashq (o'rta): this ni tiklang
- 3-mashq (qiyin): hooklarga ko'chiring
- 4-mashq: Vazifalar qadami
- 10. Real ishda
- Xulosa
- Manbalar
React class komponentlar: eski kodni o'qish, lifecycle metodlari va hooklarga ko'chirish
Qisqacha: Class komponent —
class X extends Componentvarender()metodi bor JavaScript klassi. Hooklardan oldin (2019 gacha) React shunday yozilgan, shuning uchun eski loyihalarda ko'p uchraydi. State —this.stateobyekti, yangilash —this.setState({…}). U birlashtiradi (merge),useStatekabi almashtirmaydi. Props —this.props. Effektlar o'rnida uchta lifecycle metodi bor:componentDidMount(ekranga qo'yildi),componentDidUpdate(yangilandi) vacomponentWillUnmount(olib tashlanadi) — ularning hammasiuseEffectga to'g'ri keladi.PureComponent— props va state o'zgarmasa qayta chizmaydi (memoning class versiyasi). Eng ko'p tuzoq —this: metodonClickga uzatilsa,thisyo'qoladi. Yangi kod uchun class kerak emas, faqat bitta istisno — error boundary.
Bu darsda
- Class komponentni o'qiysiz:
render,this.props,this.state,setStateva uning birlashtirishi. - Lifecycle metodlari qachon chaqirilishini konsolda ko'rasiz va ularni
useEffectbilan solishtirasiz. thisyo'qolishi tuzog'ini va uning uch davosini bilasiz.PureComponentnima qilishini tushuntira olasiz.- Class komponentni hooklarga bosqichma-bosqich ko'chirasiz va
vazifalardagiXatoChegarasini boshidan oxirigacha o'qiysiz.
Oldin bilishingiz kerak: class sintaksisi, this yo'qolishi, Effekt hayot sikli, Error boundary.
1. Nega bu kerak?
Sardor birinchi ish kunida 2018-yilda yozilgan buxgalteriya tizimini ochdi. 300 ta komponentning 200 tasi class bilan yozilgan: this.state, componentDidMount, this.handleClick = this.handleClick.bind(this). U hooklarni biladi, lekin bu kodni o'qiy olmadi. Jamoa rahbari: "Yangi kodni hook bilan yoz, lekin eskisini tuzata olishing kerak" dedi.
Bu — real holat. React 2013-yilda chiqqan, hooklar esa 2019-yilda (React 16.8). Olti yil davomida yozilgan millionlab qator kod — class komponentlarda. Kompaniyalar ularni birdaniga qayta yozmaydi. Siz esa ularni o'qiy olishingiz, tuzata olishingiz va kerak bo'lsa hooklarga ko'chira olishingiz kerak.
Ikkinchi sabab — error boundary. Error boundary darsida ko'rdik: u hozircha faqat class bo'la oladi. vazifalar ning XatoChegarasi i — class. Bugun uni har qatorigacha tushunamiz.
Hayotiy o'xshatish: eski uslubdagi qo'lyozma. Bobongizning kundaligi lotin emas, kirill yozuvida, ba'zi so'zlar eskicha. Siz bugun bu yozuvda yozmaysiz, lekin uni o'qiy olsangiz — oila tarixini bilasiz. Class komponent — React'ning "eski yozuvi": yangi kod uchun emas, mavjudini o'qish uchun.
2. Class komponent anatomiyasi
2.1 Bir xil komponent — ikki yozuvda
«Bahor» buyurtma hisoblagichi. Avval tanish funksiya:
function OrderCounter({ dish }) {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
{dish}: {count}
</button>
);
}Endi aynan shu — class:
import { Component } from "react";
class OrderCounter extends Component {
state = { count: 0 }; // useState(0) o'rni
render() {
return (
<button
onClick={() => this.setState({ count: this.state.count + 1 })}
>
{this.props.dish}: {this.state.count}
</button>
);
}
}
export default function App() {
return <OrderCounter dish="Osh" />;
}Ekranda:
Osh: 2Qatorma-qator moslik:
| Class | Funksiya |
|---|---|
class OrderCounter extends Component |
function OrderCounter(props) |
render() { return …; } |
funksiyaning return i |
this.props.dish |
{ dish } parametri |
state = { count: 0 } |
useState(0) |
this.state.count |
count |
this.setState({ count: … }) |
setCount(…) |
extends Component — meros: Component klassi setState va boshqa metodlarni beradi. state = { … } — class maydoni. Eski kodda uning o'rnida konstruktor bo'ladi:
constructor(props) {
super(props); // Component'ga props'ni berish — shart
this.state = { count: 0 };
}Ikkalasi bir xil ishni qiladi. Konstruktorli yozuv — 2018 gacha, maydonli — keyin.
2.2 setState birlashtiradi
useState bilan obyekt state'ni yangilaganda butun obyektni berish kerak edi (State III). this.setState esa berilgan maydonlarni eski state'ga qo'shadi (birlashtiradi):
import { Component } from "react";
class BookingForm extends Component {
state = { name: "", guests: 2 };
render() {
console.log("state:", JSON.stringify(this.state));
return (
<button onClick={() => this.setState({ name: "Malika" })}>
Ismni yoz
</button>
);
}
}
export default function App() {
return <BookingForm />;
}Konsolda:
state: {"name":"","guests":2}
state: {"name":"Malika","guests":2}guests yo'qolmadi — setState({ name }) faqat name ni almashtirdi. useState da setState({ name: "Malika" }) qilsangiz, guests yo'qolardi. Ko'chirishda shuni unutmang: class'dagi this.setState({ name }) → funksiyada setForm((f) => ({ ...f, name })).
Birlashtirish faqat birinchi darajada: this.setState({ address: { city } }) — address ichidagi boshqa maydonlarni o'chiradi.
setState ham asinxron va partiyalab ishlaydi (State II). Oldingi qiymatga tayansa — updater shakli: this.setState((prev) => ({ count: prev.count + 1 })).
3. this tuzog'i
3.1 Metod uzatilganda
Eski kodda ishlovchilar alohida metod sifatida yoziladi. Shunday:
import { Component } from "react";
class Counter extends Component {
state = { count: 0 };
handleClick() {
this.setState({ count: this.state.count + 1 }); // this?
}
render() {
return <button onClick={this.handleClick}>+1</button>; // ❌
}
}
export default function App() {
return <Counter />;
}Konsolda:
Uncaught TypeError: Cannot read properties of undefined (reading 'setState')
TypeError: Cannot read properties of undefined (reading 'setState')"undefined ning setState xususiyatini o'qib bo'lmaydi". this — undefined. Sabab — this yo'qolishi: onClick={this.handleClick} metodni obyektdan ajratib, oddiy funksiya sifatida uzatadi. React uni keyin handleClick() deb chaqiradi — nuqtadan oldin obyekt yo'q. Klass ichi esa qat'iy rejimda: this — undefined.
3.2 Uch davo — eski kodda uchalasi ham uchraydi
// 1) Konstruktorda bind — eng eski
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
// 2) Arrow funksiya maydoni — eng ko'p uchraydi
handleClick = () => {
this.setState({ count: this.state.count + 1 });
};
// 3) JSX ichida arrow — har renderda yangi funksiya
<button onClick={() => this.handleClick()}>+1</button>Ikkinchisi — XatoChegarasi dagi qaytaUrin = (): void => { … } va Error boundary dagi reset = () => …. Arrow funksiya o'z this ini yaratmaydi, klass maydoni esa har nusxada alohida yaratiladi — this doim shu komponent.
Funksiya komponentlarda bu muammo umuman yo'q — this ning o'zi yo'q. Bu hooklar yaratilishining sabablaridan biri edi.
4. Lifecycle metodlari
4.1 Uch asosiy metod
Class komponentning "hayoti" — ekranga qo'yilish (mount), yangilanish (update) va olib tashlanish (unmount). Har bosqichga metod bor:
import { Component, useState } from "react";
class PriceTag extends Component {
componentDidMount() {
console.log("didMount:", this.props.price);
}
componentDidUpdate(prevProps) {
const { price } = this.props;
console.log("didUpdate:", prevProps.price, "→", price);
}
componentWillUnmount() {
console.log("willUnmount");
}
render() {
console.log("render:", this.props.price);
return <p>Osh — {this.props.price} so'm</p>;
}
}
export default function App() {
const [price, setPrice] = useState(35000);
const [show, setShow] = useState(true);
return (
<div>
<button onClick={() => setPrice(38000)}>
Narxni o'zgartir
</button>{" "}
<button onClick={() => setShow(false)}>Yopish</button>
{show && <PriceTag price={price} />}
</div>
);
}Konsolda:
render: 35000
didMount: 35000
render: 38000
didUpdate: 35000 → 38000
willUnmountEkranda:
Narxni o'zgartir YopishTartib — commit qoidasi bo'yicha: avval render, keyin DOM yangilanadi, keyin did… metodlari. componentDidUpdate oldingi props'ni oladi — qaysi narsa o'zgarganini solishtirish uchun.
stateDiagram-v2
[*] --> Render1: mount
Render1 --> DidMount: DOM tayyor
DidMount --> Render2: props yoki state o'zgardi
Render2 --> DidUpdate: DOM yangilandi
DidUpdate --> Render2: yana o'zgardi
DidUpdate --> WillUnmount: olib tashlanmoqda
DidMount --> WillUnmount: olib tashlanmoqda
WillUnmount --> [*]Diagrammada render ikki joyda: mount va har yangilanishda. did… metodlari doim render'dan keyin. WillUnmount — oxirgi so'z: obunalarni bekor qilish, taymerni to'xtatish.
4.2 Bitta effekt — uch metodga bo'lingan
Class'da bitta "ish" (masalan, obuna) uch joyga tarqaladi. «Bahor» oshxona ekrani — tanlangan stolning buyurtmalariga obuna:
class TableOrders extends Component {
componentDidMount() {
this.unsubscribe = subscribe(this.props.table);
}
componentDidUpdate(prevProps) {
// stol o'zgarsa — eski obunani yopib, yangisini ochish
if (prevProps.table !== this.props.table) {
this.unsubscribe();
this.unsubscribe = subscribe(this.props.table);
}
}
componentWillUnmount() {
this.unsubscribe();
}
render() {
return <p>{this.props.table}-stol buyurtmalari</p>;
}
}Hook bilan — bitta joyda:
function TableOrders({ table }) {
useEffect(() => {
const unsubscribe = subscribe(table);
return unsubscribe; // cleanup — unmount va table o'zgarganda
}, [table]);
return <p>{table}-stol buyurtmalari</p>;
}componentDidUpdate dagi if — [table] bog'liqligining qo'lda yozilgan shakli. Eski kodda eng ko'p uchraydigan xato aynan shu if ni unutish edi. Unda stol o'zgarganda obuna eski stolda qoladi. Effekt hayot sikli darsidagi "effekt — sinxronlash, mount/unmount emas" g'oyasi aynan shu muammodan tug'ilgan.
4.3 To'liq moslik jadvali
| Class | Hook |
|---|---|
componentDidMount |
useEffect(fn, []) |
componentDidUpdate (+ if bilan solishtirish) |
useEffect(fn, [bog'liqliklar]) |
componentWillUnmount |
useEffect qaytargan cleanup |
shouldComponentUpdate |
memo (memo) |
getDerivedStateFromProps |
renderda hisoblash yoki key (State strukturasi) |
getSnapshotBeforeUpdate |
hook'da o'xshashi yo'q (scroll holatini saqlash uchun kamdan-kam) |
static getDerivedStateFromError, componentDidCatch |
hook'da yo'q — error boundary class bo'lib qoladi |
static contextType + this.context |
use(Context) / useContext |
createRef() |
useRef() |
Oxirgi uch qator diqqatga sazovor: ikki metodning hook'dagi o'xshashi yo'q. Shuning uchun ba'zi class'lar (error boundary) bugun ham yoziladi.
Tekshirib ko'ring: Class'da
componentDidMountichidasetInterval, lekincomponentWillUnmountyo'q. Komponent yopilganda nima bo'ladi?
Javob
Taymer ishlayveradi — komponent yo'q bo'lsa ham. Uning ichida this.setState bo'lsa, React o'chirilgan komponent uchun ogohlantirmaydi ham (React 18 dan), lekin xotira va protsessor isrof bo'ladi. Bu — cleanup'siz effektning class'dagi ko'rinishi. Tuzatish: componentWillUnmount() { clearInterval(this.timer); }, hook'ga ko'chirilsa — useEffect cleanup'i.
5. PureComponent
PureComponent — Component ning varianti: props va state sayoz solishtirilib, o'zgarmagan bo'lsa render chaqirilmaydi:
import { Component, PureComponent, useState } from "react";
class PlainMenu extends Component {
render() {
console.log("Component render");
return <p>Menyu: {this.props.dish}</p>;
}
}
class PureMenu extends PureComponent {
render() {
console.log("PureComponent render");
return <p>Menyu: {this.props.dish}</p>;
}
}
export default function App() {
const [guests, setGuests] = useState(1);
return (
<div>
<button onClick={() => setGuests(guests + 1)}>+1 mehmon</button>
<p>Mehmonlar: {guests}</p>
<PlainMenu dish="Osh" />
<PureMenu dish="Osh" />
</div>
);
}Konsolda:
Component render
PureComponent render
Component render
Component renderEkranda:
+1 mehmon
Mehmonlar: 3
Menyu: Osh
Menyu: OshOta ikki marta qayta chizildi. Oddiy Component har safar chizildi, PureComponent — faqat birinchi marta: dish o'zgarmagan. Funksiyadagi o'xshashi — memo(Menu). Tafsiloti, "sayoz solishtirish" tuzoqlari va qachon kerakligi — memo, useMemo, useCallback darsida.
6. Class'ni hooklarga ko'chirish
6.1 Qadamlar
Eski komponentni ko'chirish — mexanik ish, lekin tartib bilan:
class X extends Component→function X(props)(yoki{ … }destrukturizatsiya).render()ichini funksiya tanasiga ko'chiring,returnqoladi.this.props.x→x.this.statening har maydoni — alohidauseState(yoki bog'liqlari — bitta obyekt / useReducer).this.setState({ a })→setA(…); birlashtirishni unutmang.- Lifecycle'lar →
useEffect(«To'liq moslik jadvali» bo'yicha), bitta ish — bitta effekt. - Metodlar → oddiy ichki funksiyalar;
bindvathisyo'qoladi. - Testlar ishlayaptimi — tekshiring.
6.2 Misol: oshxona taymeri
Eski kod (o'qing):
import { Component } from "react";
class CookingTimer extends Component {
constructor(props) {
super(props);
this.state = { seconds: 0, running: true };
this.stop = this.stop.bind(this);
}
componentDidMount() {
this.timer = setInterval(() => {
this.setState((prev) => ({ seconds: prev.seconds + 1 }));
}, 300);
}
componentWillUnmount() {
clearInterval(this.timer);
}
stop() {
clearInterval(this.timer);
this.setState({ running: false });
}
render() {
const { seconds, running } = this.state;
return (
<div>
<p>
{this.props.dish}: {seconds} s {running ? "" : "(to'xtadi)"}
</p>
<button onClick={this.stop}>To'xtat</button>
</div>
);
}
}
export default function App() {
return <CookingTimer dish="Osh" />;
}Ekranda:
Osh: 2 s (to'xtadi)
To'xtatTaymer har 300 ms da "bir soniya" qo'shadi (tez ko'rinsin deb). 750 ms dan keyin «To'xtat» — 2 da to'xtadi.
Hook bilan — o'sha xulq:
import { useEffect, useRef, useState } from "react";
function CookingTimer({ dish }) {
const [seconds, setSeconds] = useState(0);
const [running, setRunning] = useState(true);
const timer = useRef(null); // this.timer o'rni
useEffect(() => {
timer.current = setInterval(() => {
setSeconds((s) => s + 1);
}, 300);
return () => clearInterval(timer.current); // willUnmount
}, []);
function stop() {
clearInterval(timer.current);
setRunning(false);
}
return (
<div>
<p>
{dish}: {seconds} s {running ? "" : "(to'xtadi)"}
</p>
<button onClick={stop}>To'xtat</button>
</div>
);
}
export default function App() {
return <CookingTimer dish="Osh" />;
}Ekranda:
Osh: 2 s (to'xtadi)
To'xtatNatija bir xil. Moslik: this.state → ikki useState; this.timer → useRef (render chaqirmaydigan xotira — useRef I); componentDidMount + componentWillUnmount → bitta effekt; bind → kerak emas. setState((prev) => …) → setSeconds((s) => s + 1) — updater shakli saqlandi.
6.3 Qachon ko'chirish kerak emas
Hamma eski class'ni qayta yozish — vaqt va xavf. Amaliy qoida:
- Ishlab turgan, tegilmaydigan kod — qoldiring. "Ishlayapti — tegma".
- Tez-tez o'zgaradigan kod — o'zgartirish kerak bo'lganda ko'chiring, testlar bilan.
- Error boundary — class qoladi (yoki
react-error-boundary). - Yangi kod — faqat funksiya va hooklar.
Class va funksiya komponentlar bir ilovada bemalol aralashadi: class bola funksiya ota ichida, va aksincha.
7. Vazifalar qadami: XatoChegarasi ni o'qish
Bu dars kanonda alohida qadam emas — vazifalar dagi yagona class bilan o'qish mashqi. Error boundary darsida XatoChegarasi.tsx ni ko'rgan edik. Endi uni class nuqtai nazaridan o'qiymiz (TypeScript turlari bilan, kanondan):
type Holat = { readonly xato: { readonly qiymat: unknown } | null };
export class XatoChegarasi extends Component<Props, Holat> {
override state: Holat = { xato: null };
static getDerivedStateFromError(xato: unknown): Holat {
return { xato: { qiymat: xato } };
}
override componentDidCatch(xato: unknown, malumot: ErrorInfo): void {
this.props.onXato?.(xato, malumot);
}
override componentDidUpdate(oldingi: Props): void {
if (
this.state.xato !== null &&
!Object.is(oldingi.tiklashKaliti, this.props.tiklashKaliti)
) {
this.qaytaUrin();
}
}
// Arrow — this doim shu nusxa (fallback'dagi tugmaga uzatiladi)
qaytaUrin = (): void => {
this.setState({ xato: null });
};
override render(): ReactNode { … }
}Endi har qatorni bugungi darsdan taniysiz:
| Qator | Nima |
|---|---|
extends Component<Props, Holat> |
class komponent; TypeScript'da ikki generic — props va state turlari (Generic) |
override state: Holat = { … } |
state — class maydoni; override — "ota klassdagi state ni almashtiryapman" (TS tekshiradi) |
static getDerivedStateFromError |
render bosqichi, sof — hook'da o'xshashi yo'q |
componentDidCatch |
commit'dan keyin — log |
componentDidUpdate(oldingi) |
prevProps bilan solishtirish — «Bitta effekt — uch metodga bo'lingan» dagi if naqshi |
qaytaUrin = () => … |
arrow maydon — this tuzog'ining 2-davosi |
this.setState({ xato: null }) |
birlashtiradi; bu yerda state'da bitta maydon |
override kalit so'zi — TypeScript'ning noImplicitOverride sozlamasi talab qiladi: ota klassdagi metodni almashtirsangiz, buni ochiq yozasiz. Ota klassda bunday metod bo'lmasa (masalan, componentDidCatch ni xato yozsangiz), tsc xato beradi (Klasslar TypeScript'da). Kodni o'qish uchun bu shunchaki "ota metodini almashtirish" belgisi.
componentDidUpdate dagi solishtirishni hook'da yozib bo'lmasmidi? Bo'lardi — useEffect(…, [tiklashKaliti]). Lekin chegaraning qolgan ikki metodi class talab qiladi, shuning uchun hammasi bir klassda.
8. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
Cannot read properties of undefined (reading 'setState') |
metod this siz uzatildi |
arrow maydon yoki bind |
| ko'chirgandan keyin state maydonlari yo'qoldi | setState birlashtirardi, useState almashtiradi |
setX((x) => ({ ...x, a })) yoki alohida useState |
| stol o'zgarganda obuna eskida qoldi | componentDidUpdate da if yo'q |
prevProps bilan solishtirish yoki useEffect(…, [table]) |
| yopilgandan keyin taymer ishlayveradi | componentWillUnmount yo'q |
clearInterval cleanup'da |
super(props) siz — this xatosi |
konstruktorda this dan oldin super chaqirilmagan |
super(props) birinchi qator |
UNSAFE_componentWillMount ogohlantirishi |
eski lifecycle (StrictMode) | componentDidMount / konstruktor |
9. Mashqlar
Mashqlar kurs/mashqlar/18/14-class/ da. Har yechimni «Ishga tushir» bilan sinang.
1-mashq (oson): moslik
Class'dagi narsaning hook'dagi o'xshashini yozing:
this.state = { count: 0 }→componentWillUnmount→ useEffect'ningPureComponent→this.timer(render chaqirmaydigan xotira) →
Yechim
- useState —
const [count, setCount] = useState(0). - cleanup —
useEffectqaytargan funksiya. - memo — props o'zgarmasa qayta chizmaydi.
- useRef — o'zgarsa ham render chaqirmaydi.
2-mashq (o'rta): this ni tiklang
Tugma bosilganda ilova yiqiladi. handleAdd ni arrow funksiya maydoniga aylantiring — boshqa joyga tegmang. Ishora: «Uch davo» bo'limi.
import { Component } from "react";
class AddButton extends Component {
state = { added: 0 };
handleAdd() {
this.setState((prev) => ({ added: prev.added + 1 }));
}
render() {
return (
<div>
<button onClick={this.handleAdd}>Savatga</button>
<p>Qo'shildi: {this.state.added}</p>
</div>
);
}
}
export default function App() {
return <AddButton />;
}Konsolda:
Uncaught TypeError: Cannot read properties of undefined (reading 'setState')
TypeError: Cannot read properties of undefined (reading 'setState')Yechim
import { Component } from "react";
class AddButton extends Component {
state = { added: 0 };
handleAdd = () => {
this.setState((prev) => ({ added: prev.added + 1 }));
};
render() {
return (
<div>
<button onClick={this.handleAdd}>Savatga</button>
<p>Qo'shildi: {this.state.added}</p>
</div>
);
}
}
export default function App() {
return <AddButton />;
}Ekranda:
Savatga
Qo'shildi: 1handleAdd = () => { … } — class maydoni, arrow funksiya. U this ni yaratilgan joyidan — komponent nusxasidan oladi. onClick ga uzatilsa ham this yo'qolmaydi.
3-mashq (qiyin): hooklarga ko'chiring
Stol tanlagich: tanlangan stol o'zgarsa, "ulandi: N-stol" va "uzildi: M-stol" yoziladi (obuna taqlidi). Class'ni funksiya + hooklarga ko'chiring: bitta useEffect uch lifecycle metodining o'rnini bossin. Konsol chiqishi o'zgarmasin. Ishora: «Bitta effekt — uch metodga bo'lingan» bo'limi.
import { Component, useState } from "react";
class TableFeed extends Component {
componentDidMount() {
console.log(`ulandi: ${this.props.table}-stol`);
}
componentDidUpdate(prevProps) {
if (prevProps.table !== this.props.table) {
console.log(`uzildi: ${prevProps.table}-stol`);
console.log(`ulandi: ${this.props.table}-stol`);
}
}
componentWillUnmount() {
console.log(`uzildi: ${this.props.table}-stol`);
}
render() {
return <p>{this.props.table}-stol buyurtmalari</p>;
}
}
export default function App() {
const [table, setTable] = useState(1);
const [open, setOpen] = useState(true);
return (
<div>
<button onClick={() => setTable(2)}>2-stol</button>{" "}
<button onClick={() => setOpen(false)}>Yopish</button>
{open && <TableFeed table={table} />}
</div>
);
}Konsolda:
ulandi: 1-stol
uzildi: 1-stol
ulandi: 2-stol
uzildi: 2-stolYechim
import { useEffect, useState } from "react";
function TableFeed({ table }) {
useEffect(() => {
console.log(`ulandi: ${table}-stol`);
return () => console.log(`uzildi: ${table}-stol`);
}, [table]);
return <p>{table}-stol buyurtmalari</p>;
}
export default function App() {
const [table, setTable] = useState(1);
const [open, setOpen] = useState(true);
return (
<div>
<button onClick={() => setTable(2)}>2-stol</button>{" "}
<button onClick={() => setOpen(false)}>Yopish</button>
{open && <TableFeed table={table} />}
</div>
);
}Konsolda:
ulandi: 1-stol
uzildi: 1-stol
ulandi: 2-stol
uzildi: 2-stolKonsol bir xil, kod esa uch metod o'rniga bitta effekt. componentDidUpdate dagi if — [table] ga aylandi. Cleanup'dagi table — closure: u o'sha effekt yaratilgan paytdagi stol, shuning uchun "uzildi: 1-stol" to'g'ri chiqadi. Class'da buning uchun prevProps kerak edi.
4-mashq: Vazifalar qadami
vazifalar da src/komponentlar/XatoChegarasi.tsx ni oching va «Vazifalar qadami» jadvali bo'yicha har metodni toping. Keyin uch savolga javob yozing:
- Ro'yxatdagi qator xato tashladi. Metodlar qaysi tartibda chaqiriladi?
- Server ro'yxatni yangiladi (
tiklashKalitio'zgardi). Qaysi metod chegarani tiklaydi? - Nega
qaytaUrinarrow maydon,componentDidUpdateesa oddiy metod?
Commit yo'q — bu o'qish mashqi.
Yechim
getDerivedStateFromError(render bosqichi, yangi state) →render(fallback) → commit →componentDidCatch(onXato, log).main.tsxdagionCaughtErrorham shu paytda.componentDidUpdate(oldingi): xato bor vaObject.is(oldingi.tiklashKaliti, this.props.tiklashKaliti)—false, demakthis.qaytaUrin().qaytaUrinuzatiladi — fallback funksiyasiga argument bo'lib, u yerdan tugmaningonClickiga. Uzatilgan oddiy metodthisni yo'qotardi («thistuzog'i» bo'limi).componentDidUpdateni esa React o'zichegara.componentDidUpdate(…)deb chaqiradi — nuqtadan oldin obyekt bor,thisjoyida. Ichidagithis.qaytaUrin()ham shu sababli xavfsiz bo'lardi, lekin tugmadagi chaqiruv — yo'q.
10. Real ishda
- Eski loyihalar — bank, davlat va korporativ tizimlarda 2016–2019 yillardagi React kodi ko'p. Junior dasturchining birinchi vazifalari ko'pincha shu kodda xato tuzatish.
- Ko'chirish loyihalari — "class'dan hooklarga" migratsiyasi odatda bosqichma-bosqich: yangi kod — hook, tegilgan eski kod — ko'chiriladi. Keyingi dars — React versiyasini yangilash — shu ishning versiya tomoni.
- Kutubxonalar ichida — ba'zi eski kutubxonalar (va
react-error-boundary) ichida class bor. - Intervyu savollari: "Class va funksiya komponent farqi?", "lifecycle metodlari qaysi hooklarga mos?", "nega
this.handleClicknibindqilish kerak edi?", "setStatevauseStatesetteri farqi?".
Xulosa
- Class:
extends Component,render(),this.props,this.state,this.setState(birlashtiradi, birinchi daraja). - Lifecycle:
componentDidMount,componentDidUpdate(prevProps),componentWillUnmount— hammasiuseEffect(bitta ish — bitta effekt). thistuzog'i: metod uzatilsa yo'qoladi — arrow maydon,bindyoki JSX'da arrow.PureComponent— sayoz solishtirish bilan render'ni o'tkazib yuboradi (memoo'xshashi).- Ko'chirish — mexanik qadamlar; error boundary class bo'lib qoladi; yangi kod — faqat hooklar.
vazifalar:XatoChegarasi— yagona class;override,static, arrowqaytaUrin.
Keyingi dars: React versiyasini yangilash: 18 dan 19 ga — olib tashlangan API'lar va codemod'lar bilan xavfsiz yangilash.
Manbalar
- React:
Component— react.dev/reference/react/Component (2026-10 holati, React 19.3) - React:
PureComponent— react.dev/reference/react/PureComponent - React: "Migrating from a class to a function" — react.dev/reference/react/Component#alternatives
- MDN: "Classes" — developer.mozilla.org/docs/Web/JavaScript/Reference/Classes
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!