IlmHamroh
JavaScript Full-stack/17-qism. React asoslari45/45-dars20 daqiqa
Mundarija (32)

React ilovani debug qilish: xato xabari, component stack, React DevTools va 17-qism yakuni

Qisqacha: React xatosini topishning tartibi bor. Avval xato matnini to'liq o'qing — u nima bo'lganini va ko'pincha qanday tuzatishni aytadi. Keyin component stack dan xato qaysi komponentda ekanini toping: React 19 da uni createRoot(el, { onUncaughtError }) bilan o'zingiz yozib olasiz. Build'dagi qisqartirilgan nomlarni source map asl faylga qaytaradi. Oxirida breakpoint va React DevTools bilan props, state va "nega qayta chizildi" ni ko'ring. console.log foydali, lekin u renderning "surati"ni ko'rsatadi va StrictMode'da ikki marta chiqadi.

Bu darsda

  • React xato va ogohlantirish matnlarini o'qib, sababini aniqlaysiz.
  • onUncaughtError bilan xato va component stack'ni yozib olasiz.
  • Dev va production'dagi xato ko'rinishini, source map rolini tushunasiz.
  • Breakpoint, debugger va React DevTools'dan tartib bilan foydalanasiz.
  • console.log tuzoqlarini bilasiz va 17-qismni yakunlab, vazifalar v7 ni v6 bilan raqamlarda taqqoslaysiz.

Oldin bilishingiz kerak: React DevTools bilan ishlash, Source map, DevTools bilan debug qilish, Debugging metodologiyasi.

1. Nega bu kerak?

Sardor vazifalar ga yangi statistika komponentini qo'shdi va GitHub Pages'ga chiqardi. Jasur aka telefonda ochdi — oq ekran. Na xato xabari, na tugmalar. Sardor kompyuterida npm run dev da hammasi ishlayotgan edi.

React'da render paytidagi ushlanmagan xato butun ildizni o'chiradi: ilovaning qolgan qismi ham yo'qoladi. Foydalanuvchi faqat bo'sh sahifani ko'radi. Bunday paytda "nimani o'zgartirsam ekan" deb tasodifiy tahrirlar qilish — eng sekin yo'l. Debugging metodologiyasi darsidagi tartib bu yerda ham ishlaydi: qayta hosil qil → xabarni o'qi → joyni top → farazni tekshir → tuzat.

Hayotiy o'xshatish: shifokor. U bemorni ko'rib "dorini almashtirib ko'raylik" demaydi. Avval shikoyatni tinglaydi (xato matni), qayerda og'riyotganini aniqlaydi (component stack), kerak bo'lsa rentgen qiladi (DevTools) va shundan keyin davolaydi.

2. Xato xabarini o'qish

2.1 Uch qism

React xatosi odatda uch qismdan iborat: tur (TypeError, Error), matn va ko'pincha maslahat yoki havola. Hooklar tartibi buzilganda:

jsx
import { useState } from "react";

function App() {
  const [promo, setPromo] = useState(false);
  if (promo) {
    const [percent] = useState(10); // ❌ shart ichida hook
  }
  return <button onClick={() => setPromo(true)}>Chegirma</button>;
}

Konsolda:

text
React has detected a change in the order of Hooks called by App. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://react.dev/link/rules-of-hooks
   Previous render            Next render
   ------------------------------------------------------
1. useState                   useState
2. undefined                  useState
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Uncaught Error: Rendered more hooks than during the previous render.

Ikki xabar keldi. Birinchisi — ogohlantirish: "React App dagi hooklar tartibi o'zgarganini aniqladi." Ostida jadval: oldingi renderda 2-o'rinda hech narsa yo'q edi (undefined), keyingisida — useState. Strelkalar aynan qaysi qatorda farq borligini ko'rsatadi. Ikkinchisi — xato: "Oldingi renderdagidan ko'p hook chizildi." Bu jadval — tayyor tashxis: Hooklar qoidalari buzilgan, useState shart ichida.

Xabarlarni o'qishda uch qoida:

  • Birinchi xabardan boshlang. Keyingilari ko'pincha birinchisining oqibati.
  • Komponent nomini qidiring. Xabarlarda u tez-tez bor: called by App, Check the render method of `App`.
  • Havolani oching. react.dev/link/… sahifalari aynan shu xato uchun yozilgan.

2.2 Ko'p uchraydigan React xabarlari

Kursda uchragan va bugun tekshirilgan haqiqiy matnlar (React 19.3.0, dev build):

Xabar (boshi) Ma'nosi Qayerda o'rgandik
Objects are not valid as a React child {} ichida oddiy obyekt JSX II
Each child in a list should have a unique "key" prop. ro'yxatda key yo'q Ro'yxatlar va key
Too many re-renders. React limits the number of renders… render ichida setState State I
Rendered more hooks than during the previous render. hook shart ichida Hooklar qoidalari
Maximum update depth exceeded. This can happen when a component calls setState inside useEffect… effekt har renderda setState qiladi useEffect II
Cannot update a component (\App`) while rendering a different component (`Child`)` bola render paytida otaning state'ini o'zgartirdi pastda
The result of getSnapshot should be cached… getSnapshot yangi obyekt qaytaradi useSyncExternalStore

Oxirgisidan oldingi xatoni ko'ramiz:

jsx
import { useState } from "react";

function Child({ onRender }) {
  onRender(); // ❌ render paytida otaning setState'i
  return <p>bola</p>;
}

function App() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>{count}</p>
      <Child onRender={() => setCount(1)} />
    </div>
  );
}

Konsolda:

text
Cannot update a component (`App`) while rendering a different component (`Child`). To locate the bad setState() call inside `Child`, follow the stack trace as described in https://react.dev/link/setstate-in-render

Ekranda:

text
1
bola

"Child chizilayotgan paytda App ni yangilab bo'lmaydi. Noto'g'ri setState() ni topish uchun stack trace'ga qarang." Ekran ishlayapti — lekin bu tasodif. Render sof bo'lishi kerak (Pure komponentlar): otaga xabar berish — hodisada yoki effektda.

2.3 Production'da — qisqartirilgan xabar

Production build'da React xabarlarni qisqartiradi — kod kichikroq bo'lsin. O'sha "obyekt bola" xatosini NODE_ENV=production bilan (React 19.3.0, Node 24) chiqardik:

text
Minified React error #31; visit https://react.dev/errors/31?args[]=object%20with%20keys%20%7Bsoni%7D for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

"Qisqartirilgan React xatosi #31; to'liq xabar uchun havolani oching yoki to'liq xatolar uchun qisqartirilmagan dev muhitidan foydalaning." Havola ochilsa, react.dev to'liq matnni ko'rsatadi: args[] ichida obyektning kalitlari ({soni}) bor. Qoida: production'dagi xatoni avval dev'da qayta hosil qiling — u yerda xabar to'liq va ogohlantirishlar ham bor.

3. Component stack va onUncaughtError

3.1 Oq ekranni ko'rinadigan qilish

JavaScript xatosining stack trace i (Stack trace va xato turlari) funksiyalar zanjirini ko'rsatadi. React render xatosida esa yana bir narsa kerak — component stack: xato qaysi komponent ichida va u qaysi komponentlar ichida turgani. React 19 da ildizga xato ishlovchisini berish mumkin:

jsx
import { useState } from "react";
import { createRoot } from "react-dom/client";

function Stats({ stats }) {
  return <p>Bajarildi: {stats.done}</p>; // stats berilmagan
}

function App() {
  const [shown, setShown] = useState(false);
  return (
    <main>
      <button onClick={() => setShown(true)}>Statistika</button>
      {shown && <Stats />}
    </main>
  );
}

createRoot(document.getElementById("root"), {
  onUncaughtError(error, info) {
    const names = [...info.componentStack.matchAll(/^\s*at (\S+)/gm)]
      .map((m) => m[1]);
    console.error("Ilova yiqildi:", error.message);
    console.log("Komponentlar:", names.join(" ← "));
  },
}).render(<App />);

Konsolda:

text
Ilova yiqildi: Cannot read properties of undefined (reading 'done')
Komponentlar: Stats ← main ← App

Ekranda:

text
(bo'sh)

«Statistika» bosildi — ekran butunlay bo'shadi: tugma ham yo'qoldi. React ushlanmagan render xatosida butun ildizni o'chiradi, chunki yarim chizilgan, buzuq interfeys ko'rsatishdan ko'ra bo'sh ekran xavfsizroq. Lekin endi biz bilamiz: xato Stats da, u main ichida, main esa App da. info.componentStack — satr, har qatorda at Komponent (joyi). Namunada faqat nomlarni ajratib oldik (matchAll, RegExp asoslari).

Qadam shown Nima bo'ldi Ekranda
boshida false App chizildi Statistika tugmasi
«Statistika» true Stats render paytida TypeError —
React — butun ildiz o'chirildi, onUncaughtError chaqirildi (bo'sh)

onUncaughtError xatoni ushlamaydi — u faqat xabar beradi. Ekranning bir qismini "Nimadir xato ketdi" bilan almashtirib, qolganini ishlatib turish error boundary ning ishi — Error boundary (18-qism). Ildiz sozlamasida yana ikki ishlovchi bor: onCaughtError (error boundary ushlagan xatolar) va onRecoverableError (React o'zi tiklagan xatolar, masalan hydration).

3.2 Dev va build'da component stack

vazifalar da shunday ishlovchi qo'shildi («Vazifalar qadami» da). Uni sinash uchun vaqtinchalik nusxada Statistika komponenti ?xato=1 bo'lsa xato tashlaydigan qilindi. Haqiqiy natija — ikki rejimda (natijalar/45-xato.txt, uzun yo'llar qisqartirilgan):

text
## npm run dev:
console.error: Ilova yiqildi: Sinov: Statistika yiqildi
    at Statistika (http://localhost:5802/src/komponentlar/Statistika.tsx:6:30)
    at App (http://localhost:5802/src/App.tsx:50:23)
    at TemaProvider (…/src/kontekst/TemaKonteksti.tsx:16:32)
## Build:   #ilova ichida: 0 element
console.error: Ilova yiqildi: Sinov: Statistika yiqildi
    at ke (http://127.0.0.1:5801/assets/index-DDL44VOV.js:9:59119)
    at wn (…:9:75520)

Dev'da — asl nomlar va fayl:qator:ustun (Statistika.tsx:6:30). Build'da — ke, wn: minifikator nomlarni qisqartirgan, joy esa bitta ulkan fayldagi 9:59119. Bunday stack'dan foyda yo'qmi? Bor — source map (Source map) bilan. vazifalar build'i dist/*.map fayllarini yasaydi. DevTools ularni topsa, ke ni Statistika ga, 9:59119 ni Statistika.tsx:6 ga qaytaradi. Xato yig'ish xizmatlari (Sentry kabi) ham source map'ni serverga yuklab, xuddi shunday qiladi.

Tekshirib ko'ring: onUncaughtError bo'lmasa, oq ekran sababini qanday bilardik?

Javob

Dev'da React ushlanmagan xatoni baribir konsolga yozadi (Uncaught Error: … va component stack bilan). Lekin production'da foydalanuvchi telefonida konsol yo'q va hech kim ko'rmaydi. onUncaughtError — bitta joy: u yerda xatoni konsolga yozish, serverga yuborish yoki foydalanuvchiga "Sahifani yangilang" xabarini chiqarish mumkin.

4. Breakpoint va debugger

DevTools bilan debug qilish darsidagi vositalar React'da ham to'liq ishlaydi:

jsx
function Stats({ stats }) {
  debugger; // DevTools ochiq bo'lsa — shu yerda to'xtaydi
  return <p>Bajarildi: {stats.done}</p>;
}
  • debugger — DevTools ochiq bo'lsa, ijro shu qatorda to'xtaydi; yopiq bo'lsa — hech narsa qilmaydi. Commit'dan oldin olib tashlang (ESLint no-debugger qoidasi eslatadi).
  • Sources paneli — fayl va qatorni bosib breakpoint qo'yish. Vite dev serverida asl .tsx fayllar ko'rinadi.
  • Shartli breakpoint — "faqat id === 7 bo'lsa to'xta": 1 000 qatorli ro'yxatda kerakli qatorni ushlash uchun.
  • "Pause on exceptions" — xato tashlangan joyda avtomatik to'xtash. Render xatosida bu eng tez yo'l: ijro aynan stats.done da to'xtaydi va stats ning undefined ekanini ko'rasiz.

To'xtagan paytda Scope bo'limida komponentning props'i, o'zgaruvchilari va (closure orqali) state qiymati ko'rinadi. Call Stack da esa React ichki funksiyalari ham bor — ularni "Ignore list" ga qo'shib, faqat o'z kodingizni ko'rish mumkin.

5. React DevTools

Brauzer DevTools DOM'ni ko'rsatadi, React DevTools esa komponentlar daraxtini: props, state, hooklar, kim kimni chizgan. Kengaytma Chrome, Firefox va Edge uchun bor, boshqa muhitlar uchun alohida dastur — react-devtools npm paketi (8.0.0, 2026-09-09). O'rnatish va panellar bilan React DevTools bilan ishlash darsida tanishgansiz. Bu yerda debug tartibida qo'llaymiz.

5.1 Components paneli

  • Komponentni tanlang — o'ng tomonda uning props, state va hooklari. Custom hooklar nomi bilan ko'rinadi. vazifalar da App ni tanlasangiz, hooklar ro'yxatida UrlTanlovi, Onlayn, Elon kabi bloklarni ko'rasiz — use prefiksisiz (Custom hooklar I).
  • Qiymatni o'zgartiring — state yoki props'ni panelda tahrirlab, ekran qanday javob berishini darhol ko'rish mumkin. Masalan, bo'sh ro'yxat holatini serverga tegmasdan sinash.
  • "rendered by" — bu komponentni qaysi komponent chizgani (egasi). Noto'g'ri props qayerdan kelganini topishning eng tez yo'li.
  • Komponentdan DOM'ga va aksincha — Elements panelidagi tugunni tanlab, Components'da unga mos komponentga o'tish mumkin.

5.2 "Nega qayta chizildi?"

Context II da Sardor "Highlight updates when components render" sozlamasi bilan keraksiz qayta chizishlarni ko'rgan edi: chizilgan komponent ramka bilan yonib-o'chadi. Sababini bilish uchun Profiler paneli kerak. Unda yozib olish oldidan "Record why each component rendered while profiling" sozlamasini yoqing. Keyin har komponent uchun sabab ko'rsatiladi: "props o'zgardi (qaysi biri)", "hook o'zgardi", "ota qayta chizildi". Profiler bilan chuqur o'lchash — Performance'ni o'lchash (18-qism).

5.3 Tartib

flowchart TD
  A["Xato yoki g'alati xulq"] --> B{"Konsolda xabar bormi?"}
  B -- "ha" --> C["Birinchi xabarni o'qing, havolani oching"]
  B -- "yo'q" --> D["Qayta hosil qiling: aniq qadamlar"]
  C --> E["Component stack: qaysi komponent"]
  D --> F["React DevTools: props va state to'g'rimi?"]
  E --> G["Breakpoint yoki Pause on exceptions"]
  F --> G
  G --> H["Faraz → tuzatish → test"]

Diagramma — eslab qolish uchun tartib. Konsoldagi xabar eng arzon ma'lumot, shuning uchun undan boshlanadi. Xabar bo'lmasa (ekran shunchaki noto'g'ri), avval xatoni ishonchli qayta hosil qilish kerak, keyin DevTools'da ma'lumotni tekshirish.

6. console.log tuzoqlari

console.log — eng tez vosita, lekin React'da u ba'zan yolg'on gapirgandek tuyuladi.

6.1 Snapshot va StrictMode

jsx
import { StrictMode, useState } from "react";
import { createRoot } from "react-dom/client";

function App() {
  const [count, setCount] = useState(0);
  console.log("render", count);
  function add() {
    setCount(count + 1);
    console.log("bosildi, count =", count);
  }
  return <button onClick={add}>+1</button>;
}

createRoot(document.getElementById("root")).render(
  <StrictMode>
    <App />
  </StrictMode>,
);

Konsolda:

text
render 0
render 0
bosildi, count = 0
render 1
render 1

Ekranda:

text
+1

Ikki "g'alatilik", ikkalasi ham to'g'ri xulq:

  • render ikki marta. StrictMode dev'da komponentni ikki marta chaqiradi — sofligini tekshirish uchun (StrictMode). Production'da bitta. React DevTools o'rnatilgan bo'lsa, ikkinchi chaqiruv loglari konsolda xiraroq ko'rinadi, DevTools sozlamasida esa ularni butunlay yashirish mumkin.
  • bosildi, count = 0 — setCount dan keyin ham 0. Ishlovchi shu renderning "surati" bilan ishlaydi (State II: snapshot). Yangi qiymat keyingi renderda (render 1).

6.2 Boshqa tuzoqlar

  • Obyekt keyinroq "o'zgaradi". Chrome konsoli obyektni havola bilan saqlaydi: console.log(order) dan keyin order mutatsiya qilinsa, konsolda obyektni ochganingizda yangi qiymatni ko'rasiz (yonida "i" belgisi: qiymat ochilgan paytda o'qilgan). Log paytidagi holat kerak bo'lsa — console.log(JSON.stringify(order)) yoki structuredClone(order).
  • Log noto'g'ri joyda. Render ichidagi log "nima chizilyapti"ni, effektdagisi "nima commit bo'ldi"ni, ishlovchidagisi "bosilgan paytdagi surat"ni ko'rsatadi. Savolingizga mos joy tanlang.
  • Loglar production'ga ketadi. Unutilgan console.log foydalanuvchi brauzerida ham ishlaydi va ma'lumot oshkor qilishi mumkin. vazifalar da ESLint va --max-warnings=0 bunday narsalarni commit'dan oldin ushlaydi.
  • Cheksiz sikl konsolni to'ldiradi. Effektda bog'liqliksiz setState — konsolda yuzlab Maximum update depth exceeded…. Avval effektni tuzating, keyin konsolni tozalang.

7. Vazifalar qadami: onUncaughtError, vercel.json va v7 (yakuniy)

7.1 main.tsx

Yangi branch: feat/xato-izi. Ildizga xato ishlovchisi qo'shildi:

diff
+import type { RootOptions } from "react-dom/client";
 …
+// Render xatosi (17/#45): React ildizni bo'shatadi (oq ekran)
+// va xatoni shu yerga beradi. componentStack — xato QAYSI
+// komponentlar ichida bo'lgani (App > Statistika...); dev'da
+// asl nomlar, build'da qisqartirilgan — source map (dist/*.map)
+// DevTools'da asl faylga qaytaradi. Error boundary bilan ushlash
+// (tiklash) — 18-qism
+const ildizSozlamasi: RootOptions = {
+  onUncaughtError(xato, malumot) {
+    console.error(
+      `Ilova yiqildi: ${xatoMatni(xato)}`,
+      malumot.componentStack ?? "",
+    );
+  },
+};
+
 flushSync(() => {
-  createRoot(ildiz).render(
+  createRoot(ildiz, ildizSozlamasi).render(

Izoh qatorlari telefonga sig'ishi uchun qayta bo'lindi (matni o'sha). RootOptions — react-dom/client turlari: TypeScript xato ni unknown, malumot.componentStack ni string | undefined deb biladi — shuning uchun ?? "". xatoMatni — 11-qismdan beri bor yordamchi: unknown xatodan o'qiladigan matn yasaydi. Natija — «Component stack va onUncaughtError» bo'limidagi dev/build chiqishlari.

7.2 Deploy va Service Worker

Yana ikki o'zgarish — 17-qismni yopuvchi:

  • vercel.json — Vercel uchun sozlama: build buyrug'i, dist, SPA yo'naltirish (/(.*) → /index.html) va xavfsizlik sarlavhalari (CSP <meta> dagidek, qo'shimcha frame-ancestors 'none'). Lokal serverda shu sarlavhalar bilan e2e — 159/159. Vercel hisobi bizda yo'q: deploy'ni o'z hisobingiz bilan rasmiy hujjat bo'yicha qilasiz. Pages workflow'i esa ishlayveradi.
  • skriptlar/qobiq.js — Service Worker keshi versiyasi prefiksi v6- → v7-. Eski versiyadagi foydalanuvchilarning keshi yangilanadi.

README.md, AGENTS.md va TEXNIK-QARZ.md v7 ga yangilandi. Testlar o'zgarmadi (node 156, Vitest 29), brauzer — 159/159. Diff (hujjatlar bilan): 8 fayl, +231 −184.

Commit:

text
feat: onUncaughtError bilan component stack; vercel.json; SW v7

8. 17-qism yakuni: v6 → v7

8.1 Raqamlarda

17-qism boshida vazifalar — 16-qismdagi vanilla TypeScript ilova (v6). Bugun u — to'liq React 19.3.0 ilovasi (v7). O'tish 17 ta Vazifalar qadamida (#02 dan #45 gacha) bo'ldi. Har qadamda ilova ishlab turdi: eski ilova bo'lakma-bo'lak yangisi bilan almashtirildi ("strangler" usuli). Har qadamning saqlangan holatida build, testlar va 159 ta brauzer tekshiruvi yashil.

Jadvaldan oldin bitta eslatma. Hajm, testlar va Lighthouse — yakuniy holat (#45) o'lchovi. "1 000 vazifa" qatorlari esa Mini-ilova darsida o'lchangan (holat #24, uch seriya medianalari). Keyingi qadamlar ro'yxat chizishni o'zgartirmagan.

v6 (vanilla) v7 (React)
JS+CSS (xom / gzip -9) 38 066 / 14 279 B 263 082 / 83 237 B
react-dom ulushi (minifikatsiyadan oldin) — 83.8%
testlar node:test 146 node:test 156 + Vitest 29
brauzer tekshiruvi 159/159 159/159 (17 qadamning har birida)
Lighthouse (mobil, 3 o'lchov) 100/100/100/100 98–99/100/100/100
1 000 vazifa: bitta katak (#24) 47–77 ms 19–20 ms
1 000 vazifa: qidiruv, faqat JS (#24) 11–13 ms 16–19 ms
Brauzer yuklaydigan JS+CSS (gzip -9)
  • v6 vanilla14 279 B14,3 KB
  • #02 React oroli81 691 B81,7 KB
  • #24 to'liq UI83 107 B83,1 KB
  • #45 v7 yakuniy83 237 B83,2 KB

Manba: vazifalar kanoni: olchov/hajm.mjs, natijalar/tekshiruv-02.txt, 24-taqqoslash.txt, tekshiruv-45.txt (2026-10-12/13)

Grafikdagi asosiy saboq: React'ning narxi bir martalik — birinchi orol (#02) hajmni ~67 KB gzip oshirdi, keyingi 43 dars esa jami 1.5 KB qo'shdi. Evaziga nima oldik:

  • Deklarativ UI — render() va qo'lda DOM yangilash yo'q; ekran holatdan chiziladi.
  • Bitta katak o'zgarishi 2.4–4 marta tezroq — React faqat o'zgargan qatorni yangilaydi. Ko'p qator o'zgarganda (qidiruv) esa biroz sekinroq — halol natija.
  • Holat bir joyda — reducer (7 amal, 7 test), URL va internet holati tashqi manbadan, tema va qator hodisalari Context'da, takrorlanadigan mantiq — 5 ta custom hook'da.
  • Komponent testlari — Vitest + Testing Library (0 → 29).

8.2 vazifalar dagi hooklar xaritasi

Hook Qayerda Dars
useState qidiruv, tarmoq, dialog, forma R-12–R-19
useReducer vazifalar + tahrir R-39
useEffect, useEffectEvent localStorage, tablar, server R-26–R-31
useRef taymer, sinxron xo'jaligi, fokus Map R-33–R-34
useId aria-labelledby R-37
useSyncExternalStore URL, internet, tizim temasi R-38
use + Context TemaProvider, qator hodisalari R-41–R-42
custom hooklar useOnlayn, useUrlTanlovi, useElon, useOynaHodisasi, useMediaQuery R-43–R-44

8.3 18-qism nimaga quriladi

TEXNIK-QARZ.md da 17-qismdan qolgan ishlar ochiq yozilgan. 18-qism ("React chuqur") ularni yopadi. Ro'yxat 18-qism darslari tartibida:

  • Concurrent rendering (18/#01–#03) — useTransition, useDeferredValue, Suspense. Bugungi "tearing" (useSyncExternalStore) shu yerda to'liq ma'no oladi.
  • Import va Actions (qarz 34) (18/#05–#07) — fayl o'qilayotganda eski renderning funksiyasi ishlaydi; Actions va useActionState bilan tuzatamiz. Shu yerda Formalar II dagi <form action> ga ham qaytamiz: u nega kanonga kirmagani o'lchangan edi. Uni useOptimistic bilan birga qayta ko'rib chiqamiz.
  • Oq ekran (18/#08) — bugun xatoni faqat yozib olamiz; Error boundary bilan ekranning bir qismini tiklaymiz.
  • Hajm (qarz 31) (18/#09) — lazy bilan eksport/import va dialogni alohida yuklash, o'lchov bilan (lazy va code splitting).
  • Qayta chizish (qarz 35) (18/#20–#21) — memo, useMemo, useCallback va React Compiler — o'lchab (memo, React Compiler).
  • Fokus va flushSync (qarz 33) (18/#40) — Fokus boshqaruvi.

9. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
production'da oq ekran, konsol bo'sh render xatosi, hech kim yozmaydi onUncaughtError; dev'da qayta hosil qiling
Minified React error #N production build havolani oching yoki dev'da qayta hosil qiling
stack'da ke, wn minifikatsiya source map (dist/*.map)
log ikki marta StrictMode (dev) normal; production'da bitta
log eski qiymatni ko'rsatadi snapshot: setState dan keyin keyingi render yoki effektda log
konsoldagi obyekt "o'zgarib qoldi" Chrome obyektni havola bilan ko'rsatadi JSON.stringify yoki structuredClone
debugger foydalanuvchida commit'da qolib ketgan ESLint no-debugger

10. Mashqlar

Mashqlar kurs/mashqlar/17/45-debug/ da.

1-mashq (oson): xabarni o'qing

Quyidagi komponent yiqiladi. Kodni ishga tushirmasdan javob bering, keyin «Ishga tushir» bilan tekshiring.

jsx
function Price({ dish }) {
  return <b>{dish.price.toFixed(0)} so'm</b>;
}

function Menu() {
  const dishes = [{ name: "Osh", price: 35000 }, { name: "Choy" }];
  return (
    <ul>
      {dishes.map((d) => (
        <li key={d.name}>{d.name}: <Price dish={d} /></li>
      ))}
    </ul>
  );
}

function App() {
  return <Menu />;
}
  • Xato matnidagi xususiyat nomi: reading ''
  • Xato qaysi komponentda:
  • Qaysi taom sabab:
Yechim

Konsolda:

text
Uncaught TypeError: Cannot read properties of undefined (reading 'toFixed')

"undefined ning toFixed xususiyatini o'qib bo'lmaydi." undefined — dish.price: "Choy" da narx yo'q. Xato Price da (saytdagi qutida Komponentlar: App → Menu → ul → li → Price). Tuzatish — ma'lumotni to'g'rilash yoki narx yo'qligini ko'rsatish: {dish.price === undefined ? "narx yo'q" : …}.

2-mashq (o'rta): cheksiz sikl

Komponent sahifa sarlavhasini savatdagi taomlar soniga moslashi kerak edi. Lekin konsol Maximum update depth exceeded… ga to'lib ketdi va hisoblagich to'xtamay o'sdi. Kodni ishga tushirmang (sikl!) — xatoni toping va tuzating. Sarlavha faqat items o'zgarganda yangilansin, title uchun alohida state kerak emas.

jsx
function Cart({ items }) {
  const [title, setTitle] = useState("");
  useEffect(() => {
    setTitle(`Savat (${items.length})`);
    document.title = title;
  });
  return <p>{title}</p>;
}
Yechim
jsx
import { useEffect } from "react";

function Cart({ items }) {
  const title = `Savat (${items.length})`; // hosilaviy — state emas
  useEffect(() => {
    document.title = title;
    console.log("sarlavha:", document.title);
  }, [title]);
  return <p>{title}</p>;
}

function App() {
  return <Cart items={["Osh", "Manti"]} />;
}

Konsolda:

text
sarlavha: Savat (2)

Ekranda:

text
Savat (2)

Ikki xato bor edi. Birinchisi — bog'liqliklarsiz effektda setTitle: har render → effekt → setTitle → render. setTitle har safar yangi satr bilan chaqirilmasa ham, React bunday effektni xavfli deb biladi. Bizning vazifalar dagi ESLint (eslint-plugin-react-hooks 7.1.1) bu kodni commit'dan oldin ushlardi: set-state-in-effect qoidasi — xato darajasida. Ikkinchisi — title hosilaviy qiymat: u items dan hisoblanadi, state'ga ehtiyoj yo'q (State strukturasi). Effekt faqat tashqi tizim (document.title) bilan sinxronlash uchun qoldi (Sizga effekt kerak emas).

3-mashq (qiyin): "nega qayta chizildi?" hook'i

React DevTools'dagi "Record why each component rendered" ning kichik nusxasini yozing: useWhyRender(name, props) — komponent har qayta chizilganda qaysi props o'zgarganini konsolga yozadi (Object.is bilan). Birinchi renderda hech narsa yozmasin. O'zgargan props yo'q bo'lsa — "Badge: props o'zgarmadi (ota qayta chizildi)".

Ishora: oldingi props'ni useRef da saqlang (useRef I), solishtirish va yangilashni effektda qiling (render toza qolsin).

Yechim
jsx
import { useEffect, useRef, useState } from "react";

function useWhyRender(name, props) {
  const previous = useRef(null);
  useEffect(() => {
    if (previous.current !== null) {
      const changed = Object.keys(props).filter(
        (key) => !Object.is(previous.current[key], props[key]),
      );
      console.log(
        changed.length > 0
          ? `${name}: o'zgardi — ${changed.join(", ")}`
          : `${name}: props o'zgarmadi (ota qayta chizildi)`,
      );
    }
    previous.current = props;
  });
}

function Badge(props) {
  useWhyRender("Badge", props);
  return <p>Savatda: {props.count}</p>;
}

function App() {
  const [count, setCount] = useState(0);
  const [tick, setTick] = useState(0);
  return (
    <div>
      <Badge count={count} />
      <button onClick={() => setCount(count + 1)}>Osh +</button>{" "}
      <button onClick={() => setTick(tick + 1)}>Soat</button>
    </div>
  );
}

Konsolda:

text
Badge: o'zgardi — count
Badge: props o'zgarmadi (ota qayta chizildi)

Ekranda:

text
Savatda: 1
Osh + Soat

«Soat» App ning state'ini o'zgartirdi — Badge props'i o'sha, lekin u baribir qayta chizildi: React sukut bo'yicha otasi chizilgan bolalarni ham chizadi. Buni to'xtatish — memo ning ishi (memo, useMemo, useCallback). Hook effektda ishlaydi: render paytida log va ref yozuvi bo'lsa, StrictMode'da ikki marta chiqib, chalg'itardi.

11. Real ishda

  • Xato yig'ish xizmatlari (Sentry, Bugsnag va boshqalar) aynan onUncaughtError/onCaughtError va source map bilan ishlaydi: foydalanuvchidagi xato component stack bilan dasturchiga yetib keladi.
  • "Qayta hosil qilish qadamlari" — har xato hisobotining (bug report) majburiy qismi; ularsiz debug taxminga aylanadi.
  • React DevTools — frontend dasturchining kundalik vositasi: props'ni tekshirish, keraksiz qayta chizishni topish, Profiler bilan sekin komponentni aniqlash.
  • Intervyu savollari: "Oq ekran — qanday debug qilasiz?", "Component stack nima?", "Production'dagi Minified React error ni qanday o'qiysiz?", "Nega log ikki marta chiqyapti?".

Xulosa

  • Xabarni to'liq o'qing, birinchisidan boshlang; React matnlari ko'pincha tashxis va havolani beradi.
  • Ushlanmagan render xatosi butun ildizni o'chiradi; createRoot(el, { onUncaughtError }) xato va component stack'ni beradi.
  • Production'da xabar qisqartirilgan (Minified React error #N) va nomlar minifikatsiyalangan — havola, dev rejimi va source map yordam beradi.
  • Breakpoint, "Pause on exceptions" va React DevTools (props, state, hooklar, "rendered by", Profiler) — taxmin o'rniga dalil.
  • console.log — renderning surati; StrictMode'da ikki marta; obyektni log paytidagi holati bilan ko'rish uchun nusxa oling.
  • vazifalar v7: React 19.3.0, 17 qadam, har qadamda 159/159. Narxi — +69 KB gzip (14.3 → 83.2 KB); evaziga deklarativ UI, reducer, Context, hooklar va 29 komponent testi. 18-qism — concurrent rendering, Actions, error boundary, lazy, memo.

Keyingi qism: 18-qism: React chuqur — Concurrent rendering va useTransition — React ishni qanday bo'laklarga bo'lishini va shoshilinch bo'lmagan yangilanishni qanday kechiktirishni o'rganamiz.

Manbalar

  • React: createRoot — onUncaughtError, onCaughtError, onRecoverableError — react.dev/reference/react-dom/client/createRoot
  • React 19 e'loni: "Better error reporting" (2024-12-05) — react.dev/blog/2024/12/05/react-19
  • React: "React Developer Tools" — react.dev/learn/react-developer-tools
  • React xato kodlari: react.dev/errors
  • react-devtools 8.0.0 (npm, 2026-10-13 holati)
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
React ilovani debug qilish: xato xabari, component stack, React DevTools va 17-qism yakuni — IlmHamroh