IlmHamroh
JavaScript Full-stack/18-qism. React chuqur15/42-dars22 daqiqa
Mundarija (34)

React versiyasini yangilash: 18 dan 19 ga — olib tashlangan API'lar, codemod va peer xatolari

Qisqacha: React 19 bir nechta eski API'ni butunlay olib tashladi: ReactDOM.render (o'rniga createRoot), string ref (ref="input"), funksiya komponentdagi propTypes va defaultProps. Ba'zilari xato beradi, ba'zilari esa jim e'tiborsiz qoldiriladi — bu eng xavflisi. Tartib: avval React 18.3 ga o'ting va ogohlantirishlarni tuzating, keyin codemod'larni ishga tushiring (npx codemod … react-19-migration-recipe, npx types-react-codemod preset-19), natijani ko'z bilan tekshiring va kutubxonalarning peer bog'liqliklarini hal qiling. Biz codemod'larni haqiqiy eski loyihada ishga tushirdik: ular ishning katta qismini qiladi, lekin bitta faylni buzdi va ikkitasini o'tkazib yubordi.

Bu darsda

  • React 19 da olib tashlangan API'larni va ularning o'rnini bilasiz.
  • Qaysi o'zgarish xato beradi, qaysi biri jim o'tadi — natija oynasida ko'rasiz.
  • Yangilash tartibini (18.3 → codemod → qo'lda tekshiruv → testlar) qo'llay olasiz.
  • Codemod chiqishini o'qib, uning xatolarini topasiz.
  • ERESOLVE peer xatosini va npm ls dagi invalid ni tushunib, to'g'ri yechim tanlaysiz.

Oldin bilishingiz kerak: Bog'liqliklarni yangilash strategiyasi, node_modules ichida: peer xatolari, Class komponentlarni o'qish, useRef II: DOM elementlari va ref prop.

1. Nega bu kerak?

Class komponentlarni o'qish darsida Sardor eski kodni o'qishni o'rgangan edi. Endi Jasur aka unga yangi ish berdi: «Bahor»ning buyurtma paneli 2022 yilda React 18 da yozilgan. Unga React 19 dagi Actions va useOptimistic kerak (Actions). Demak, avval React'ni yangilash kerak.

Sardor package.json da "react": "^18.3.1" ni 19.3.0 ga o'zgartirib, npm install qilsa bo'ladimi? Bo'ladi, lekin natija uch xil bo'lishi mumkin. Ilova ochilmay qoladi (TypeError). Yoki ochiladi, lekin bir joyda rang yo'qoladi va hech kim sezmaydi. Yoki npm install ning o'zi ERESOLVE bilan to'xtaydi. Uchalasi ham shu darsda — haqiqiy chiqishlar bilan.

Bizning vazifalar loyihamiz React 19 da tug'ilgan (Birinchi React loyiha — 19.2.8 shablon, o'rnatilgani 19.3.0). Unda yangilanadigan narsa yo'q, shuning uchun bu dars kanonda qadam emas. Lekin ishga kirganingizda birinchi uchraydigan vazifalardan biri — aynan eski loyihani yangilash.

Hayotiy o'xshatish: oshxonada eski gaz plitasini induksion plitaga almashtirish. Ko'p qozon yangi plitada ham ishlaydi. Alyuminiy qozon esa plitaga qo'yilganda xato bermaydi — shunchaki qizimaydi. Eng xavflisi — shu jim ishlamaslik.

2. Nima olib tashlandi

2.1 Jadval

React 19 e'lonidan oldin React jamoasi yangilash qo'llanmasini chiqardi (react.dev, "React 19 Upgrade Guide", 2024-04-25). Undagi asosiy olib tashlanganlar:

Eski (React 18) React 19 da O'rniga
ReactDOM.render, hydrate yo'q createRoot, hydrateRoot
unmountComponentAtNode yo'q root.unmount()
findDOMNode yo'q ref
string ref: ref="input" xato ref callback yoki createRef
funksiyada propTypes jim e'tiborsiz TypeScript turlari
funksiyada defaultProps jim e'tiborsiz standart parametr
act (react-dom/test-utils) ko'chdi import { act } from "react"
useFormState (canary) nomi o'zgardi useActionState

Jadvaldagi "jim e'tiborsiz" so'zlariga e'tibor bering. Ular eng xavfli qatorlar — keyingi bo'limlarda o'zingiz ko'rasiz.

Yana uchtasi kamroq uchraydi: eski context (contextTypes, getChildContext) — o'rniga createContext (Context I); React.createFactory — o'rniga JSX; UMD build'lar (<script src="react.production.min.js">) — endi faqat ES modul yoki CDN'dagi ESM.

2.2 ReactDOM.render — endi yo'q

Saytdagi natija oynasida ham React 19.3.0 ishlaydi. react-dom dagi funksiyalarni sanab ko'ramiz:

jsx
import ReactDOM from "react-dom";

console.log("render:", typeof ReactDOM.render);
console.log("hydrate:", typeof ReactDOM.hydrate);
console.log("findDOMNode:", typeof ReactDOM.findDOMNode);
console.log("unmount…:", typeof ReactDOM.unmountComponentAtNode);
console.log("flushSync:", typeof ReactDOM.flushSync);
console.log("createPortal:", typeof ReactDOM.createPortal);

function App() {
  return <p>Salom, «Bahor»!</p>;
}

Konsolda:

text
render: undefined
hydrate: undefined
findDOMNode: undefined
unmount…: undefined
flushSync: function
createPortal: function

To'rttasi — undefined. Eski main.jsx dagi ReactDOM.render(<App />, el) qatori undefined ni funksiya sifatida chaqiradi va TypeError: … is not a function beradi. Oq ekran — lekin hech bo'lmasa xato baland ovozda. flushSync va createPortal (Portallar) esa react-dom da qoldi.

To'g'ri ko'rinishi — Birinchi React loyiha darsidagi main.tsx:

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

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

Farq faqat sintaksisda emas. ReactDOM.render React 18 da ham "eski rejim" edi: concurrent rendering, transition va automatic batching faqat createRoot bilan ishlardi (Concurrent rendering). React 18 ga o'tib, render ni qoldirgan loyihalar aslida React 17 kabi ishlab kelgan.

2.3 defaultProps va propTypes — jim e'tiborsiz

Endi eng xavfli holat. Eski kodda funksiya komponentga standart qiymat shunday berilardi:

jsx
function Badge({ color, text }) {
  console.log("color:", color);
  return <p>{text}: {color}</p>;
}
Badge.defaultProps = { color: "yashil" };
Badge.propTypes = { text: () => new Error("matn shart") };

function App() {
  return <Badge text="Osh" />;
}

Konsolda:

text
color: undefined

Ekranda:

text
Osh:

React 18 da bu yerda color: yashil chiqardi. React 19 da defaultProps funksiya komponent uchun o'qilmaydi — va bir og'iz ogohlantirish ham yo'q. propTypes ham: tekshiruv funksiyasi xato qaytaradi, lekin React uni umuman chaqirmaydi. Ilova ishlayveradi, faqat nishon rangsiz. Buni foydalanuvchi sezadi, test esa sezmasligi mumkin.

O'rniga — JavaScript'ning o'z imkoniyati, standart parametr (Destructuring):

jsx
function Badge({ color = "yashil", text }) {
  console.log("color:", color);
  return <p>{text}: {color}</p>;
}

function App() {
  return <Badge text="Osh" />;
}

Konsolda:

text
color: yashil

propTypes o'rniga — TypeScript (React + TS I). Turlar xatoni ilova ishga tushishidan oldin, kompilyatsiyada topadi. propTypes esa faqat dev rejimda, ishlash paytida ogohlantirardi.

2.4 Class komponentda defaultProps qoladi

Bir istisno bor: class komponentda static defaultProps ishlayveradi. Class'da standart parametrga o'xshash qulay joy yo'q:

jsx
import { Component } from "react";

class Card extends Component {
  static defaultProps = { color: "yashil" };
  render() {
    return <p>Rang: {this.props.color}</p>;
  }
}

function App() {
  return <Card />;
}

Ekranda:

text
Rang: yashil

Shuning uchun "defaultProps ni hamma joydan o'chiring" degan qoida noto'g'ri. Funksiyalarda — standart parametrga, class'larda — qoldiring.

2.5 String ref — xato

Class komponentlarni o'qish darsida eski kodda this.refs ni uchratgansiz. React 19 da bunday kod chizilmaydi:

jsx
import { Component } from "react";

class Search extends Component {
  componentDidMount() {
    this.refs.input.focus();
  }
  render() {
    return <input ref="input" />;
  }
}

function App() {
  return <Search />;
}

Konsolda:

text
Uncaught Error: Expected ref to be a function, an object returned by React.createRef(), or undefined/null.

"ref funksiya, React.createRef() qaytargan obyekt yoki undefined/null bo'lishi kerak edi." Satr bu ro'yxatda yo'q. Saytda «Komponentni chizishda xato» qutisi chiqadi. Tuzatish — ref callback (keyingi bo'limda codemod aynan shuni yozadi) yoki createRef.

Tekshirib ko'ring: Uchta o'zgarish: ReactDOM.render, string ref va funksiyadagi defaultProps. Qaysi biri yangilashdan keyingi qo'lda tekshiruvda eng oson o'tkazib yuboriladi va nega?

Javob

defaultProps. Qolgan ikkitasi xato tashlaydi — ilova ochilmaydi yoki komponent qizil quti bilan to'xtaydi, buni darhol ko'rasiz. defaultProps esa jim yo'qoladi: komponent chiziladi, faqat bir qiymat undefined. Shuning uchun uni ko'z bilan emas, qidiruv bilan topish kerak: git grep -n "defaultProps".

3. Yangilash tartibi

3.1 Avval 18.3

React jamoasi o'tishni yengillatish uchun alohida versiya chiqardi: React 18.3 (2024-04-25). U React 18.2 bilan bir xil ishlaydi, faqat 19 da olib tashlanadigan har API uchun konsolga ogohlantirish qo'shadi. Ya'ni 18.3 — "19 ga tayyormisiz?" degan tekshiruvchi.

Tartib shunday:

flowchart TD
  A["18.3 ga o'tish"] --> B["Dev'da ilovani aylanib chiqish"]
  B --> C{"Ogohlantirish bormi?"}
  C -->|"ha"| D["Tuzatish yoki codemod"]
  D --> B
  C -->|"yo'q"| E["19 ga o'tish + codemod"]
  E --> F["Diff'ni ko'z bilan o'qish"]
  F --> G["tsc, test, e2e, qo'lda"]
  G --> H["Bitta commit, PR"]

Har qadam alohida commit bo'lgani yaxshi: muammo chiqsa, qaysi qadam sabab bo'lganini git bisect tez topadi (Git tarixini qidirish). Diagrammadagi halqaga qarang: React 18.3 ogohlantirishlari tugamaguncha 19 ga o'tilmaydi.

3.2 Yangi JSX transform

Yana bitta shart: loyiha yangi JSX transform bilan yig'ilishi kerak (2020 yildan beri bor — import React yozmasdan JSX ishlatish, JSX I). Eski transform bilan React 19 ogohlantiradi. Vite, Next.js va zamonaviy shablonlarda u allaqachon yoqilgan — tekshirish oddiy: komponent fayllarida import React from "react" shart bo'lmasa, yangisi ishlayapti.

3.3 Yangilanadigan paketlar

Bir vaqtda to'rt paket: react, react-dom, @types/react, @types/react-dom. Turlarni unutmang — React 19 da ular ham o'zgardi (keyingi bo'limda TypeScript xatolari). Hammasi aniq versiya bilan:

bash
npm install --save-exact react@19.3.0 react-dom@19.3.0
npm install -D --save-exact \
  @types/react@19.3.0 @types/react-dom@19.3.0

--save-exact — package.json ga ^ siz yozadi (Semver): katta yangilashdan keyin versiya o'z-o'zidan suzib ketmasin.

4. Codemod: avtomatik tuzatish

4.1 Codemod nima

Codemod (code modification — kodni o'zgartirish) — kodni matn sifatida emas, sintaksis daraxti (AST) sifatida o'qib, qoida bo'yicha qayta yozadigan dastur. "ReactDOM.render(X, Y) ni createRoot(Y).render(X) ga almashtir" kabi qoidani yuzlab faylga bir soniyada qo'llaydi. Oddiy "qidirish va almashtirish"dan farqi — u izoh ichidagi so'zga tegmaydi va qavslarni to'g'ri tushunadi.

React 19 uchun ikki to'plam bor:

Vosita Nima qiladi Fayllar
react-19-migration-recipe (codemod.com registri) render, string ref, act, useFormState, PropTypes JS va TS
types-react-codemod preset-19 TypeScript turlaridagi o'zgarishlar faqat .ts, .tsx

Eski react-codemod npm paketi (5.4.4) ham bor, lekin unda React 19 uchun transformlar yo'q — biz sinab ko'rdik: replace-reactdom-render ni so'raganda "Invalid transform choice" deb, faqat eski (16–18 davri) ro'yxatni chiqardi. React hujjati hozir npx codemod buyrug'ini ko'rsatadi.

4.2 Sinov loyihasi

Codemod'ni haqiqiy kodda ko'ramiz. %TEMP% da kichik eski loyiha yasadik — uchta fayl, React 18 uslubida. main.jsx:

jsx
import ReactDOM from "react-dom";
import App from "./App.jsx";

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

App.jsx da — propTypes va defaultProps li Badge, string ref'li Search class komponenti («Nima olib tashlandi» bo'limidagi misollar). Va test fayli App.test.jsx, unda import { act } from "react-dom/test-utils". Papka git ostida — codemod'dan keyin git diff bilan aniq nima o'zgarganini ko'ramiz.

4.3 Ishga tushirish

bash
npx codemod@1.18.3 run react-19-migration-recipe --target src \
  --no-interactive --disable-analytics --allow-dirty

Bayroqlar: --target src — qaysi papka; --no-interactive — savol bermasin; --disable-analytics — telemetriya (foydalanish statistikasi) yubormasin; --allow-dirty — git'da saqlanmagan o'zgarish bo'lsa ham ishlasin.

Bitta narsani bilib qo'ying: --disable-analytics bilan ham CLI internetga chiqadi. Retsept kompyuteringizda yo'q — u codemod.com registridan anonim (akkauntsiz) yuklab olinadi. Statistika o'chadi, lekin registrga murojaat baribir bo'ladi. Kompaniya tarmog'i tashqi saytlarni yopgan bo'lsa, buyruq shu yerda to'xtaydi. Oxirgisisiz birinchi urinishda haqiqatan to'xtadi: You have uncommitted changes in src. Use --allow-dirty to proceed anyway. Windows'da git qator oxirlarini (CRLF) o'zgargan deb ko'rsatgan edi. O'z loyihangizda bayroqni emas, avval commit qilishni tanlang — shunda diff toza bo'ladi.

Chiqishda ikki narsaga qarang: qaysi codemod'lar ishladi (Running … qatorlari) va oxiridagi Modified soni. Chiqish (rang belgilarisiz, qisqartirilgan):

text
⏺ Replace ReactDOM.render with createRoot
  Running react-19-replace-reactdom-render
⏺ Replace string refs with callback refs
  Running react-19-replace-string-ref
⏺ Migrate act from react-dom/test-utils to react
  Running react-19-replace-act-import
⏺ Replace useFormState with useActionState
  Running react-19-replace-use-form-state
⏺ Convert PropTypes to TypeScript props
  Running react-prop-types-typescript
Workflow completed in 3.0s

Run summary
  Modified     3
  Unmodified   9

Nima bo'ldi? Retsept (recipe) — beshta alohida codemod ketma-ket ishladi va Modified 3 deb hisobot berdi. Qaysi 3 tasi va to'g'ri o'zgardimi — bu yerda yozilmagan. Shuning uchun eng muhim qism — git diff.

4.4 Diff'ni o'qish

main.jsx — to'g'ri:

diff
+import { createRoot } from "react-dom/client";
 import ReactDOM from "react-dom";
 import App from "./App.jsx";
 
-ReactDOM.render(<App />, document.getElementById("root"));
+const root = createRoot(document.getElementById("root"));
+root.render(<App />);

Faqat import ReactDOM qoldi — endi u ishlatilmaydi. ESLint no-unused-vars buni ko'rsatadi, qo'lda o'chirasiz.

App.jsx dagi string ref — ishlaydi:

diff
   render() {
-    return <input ref="input" />;
+    return (<input ref={(ref) => {
+        this.refs.input = ref;
+      }} />);
   }

Ref callback elementni this.refs.input ga yozadi, componentDidMount dagi this.refs.input.focus() o'zgarmaydi. Biz natijani natija oynasida sinadik — componentDidMount da this.refs.input.tagName INPUT ni chiqardi. Formatlash g'alati, buni Prettier tuzatadi (Prettier).

Va mana muammo — Badge:

diff
 import { Component } from "react";
-import PropTypes from "prop-types";
 
-function Badge({ color, text }) {
+interface BadgeProps {
+  text: string
+}
+
+function Badge({ color, text }: BadgeProps) {
   return <span style={{ color }}>{text}</span>;
 }
-Badge.propTypes = { text: PropTypes.string.isRequired };
 Badge.defaultProps = { color: "green" };

Uchta muammo bir joyda:

  1. .jsx faylga TypeScript yozildi. interface va : BadgeProps — JavaScript sintaksisi emas. Vite build .jsx faylni TS sifatida o'qimaydi va sintaksis xatosi beradi. Codemod fayl kengaytmasiga qaramadi.
  2. color turda yo'q. BadgeProps da faqat text, chunki propTypes da color yo'q edi. Fayl .tsx ga o'tkazilsa, tsc "Property 'color' does not exist" deydi.
  3. defaultProps tegilmadi. Retseptda u uchun codemod yo'q — u registrda alohida (react-19-replace-default-props). Demak, eng jim xato — eng xavflisi — joyida qoldi.

Yana bitta: App.test.jsx dagi act importi o'zgarmadi. Shubha bo'ldi va o'sha codemod'ni alohida ishga tushirdik: .jsx faylda Modified 0, Unmodified 0 — faylni umuman ko'rmadi. Xuddi shu kodni .tsx faylga qo'ysak — import { act } from "react"; ga almashdi. Ya'ni codemod (registrdagi 2026-10 holati) .jsx test fayllarini o'tkazib yuboradi.

Diqqat: Codemod — yordamchi, hakam emas. "Workflow completed" degani "hamma narsa to'g'ri" degani emas. Har diff qatorini o'qing, keyin qolganini qidiruv bilan tekshiring: git grep -nE "ReactDOM\.render|findDOMNode|defaultProps|propTypes|test-utils" src.

4.5 TypeScript turlari: types-react-codemod

@types/react 19 da ham o'zgarishlar bor. Eski uslubdagi .tsx fayl:

tsx
import { useRef } from "react";

export function Timer(): JSX.Element {
  const id = useRef<number>();
  const box = useRef<HTMLDivElement>(null);
  return <div ref={(el) => (box.current = el)}>{id.current}</div>;
}

Xato:

text
TS2503: Cannot find namespace 'JSX'.
TS2554: Expected 1 arguments, but got 0.
TS2322: Type '(el: HTMLDivElement | null) => HTMLDivElement | null' is not assignable to type 'Ref<HTMLDivElement> | undefined'.

Uch xato, uch sabab:

  • TS2503 — "JSX nomlar fazosi topilmadi". React 19 turlarida global JSX yo'q, u react dan import qilinadi (import type { JSX } from "react"). Turli kutubxonalarning JSX'i bir-biriga aralashmasin deb shunday qilindi.

  • TS2554 — "1 ta argument kutilgan, 0 ta berildi". useRef endi boshlang'ich qiymatsiz chaqirilmaydi: useRef<number>(undefined) yoki useRef<number | null>(null).

  • TS2322 — "(el) => HTMLDivElement | null turi Ref<HTMLDivElement> ga mos emas". Ref callback (el) => (box.current = el) qiymat qaytaradi (tayinlash ifodasi qiymat beradi). React 19 da ref callback qaytargan funksiya — cleanup (useRef II), shuning uchun yangi turlar callback'dan faqat funksiya yoki hech narsa kutadi. React 18 turlarida bu qator xatosiz edi.

bash
npx types-react-codemod@3.5.3 preset-19 ./src --yes

--yes — barcha savollarga "ha" (aks holda qaysi transformlarni tanlash so'raladi). Chiqishning oxiri:

text
Results:
0 errors
0 unmodified
0 skipped
1 ok
Time elapsed: 25.540seconds

Diff:

diff
-import { useRef } from "react";
+import { useRef, type JSX } from "react";
 
 export function Timer(): JSX.Element {
-  const id = useRef<number>();
+  const id = useRef<number>(undefined);
   const box = useRef<HTMLDivElement>(null);
-  return <div ref={(el) => (box.current = el)}>{id.current}</div>;
+  return (
+    <div ref={el => {
+      (box.current = el);
+    }}>{id.current}</div>
+  );
 }

Uchala o'zgarish to'g'ri — uchta xatoning har biriga bittadan. Ref callback endi jingalak qavsli tana — hech narsa qaytarmaydi. Ortiqcha qavslar (box.current = el); — zararsiz, Prettier ularni qoldiradi, o'zingiz olib tashlashingiz mumkin.

Tekshirib ko'ring: Codemod "Modified 3" dedi. Qaysi uch fayl ekanini qanday aniq bilasiz va nima uchun bu son o'zi yetarli emas?

Javob

git status va git diff bilan — shuning uchun codemod'dan oldin commit kerak. Son yetarli emas, chunki u "nechta fayl o'zgardi" ni aytadi, "to'g'ri o'zgardimi" ni emas. Bizning sinovda o'zgargan fayllardan biri (App.jsx) buzildi, o'zgarmaganlar orasida esa o'zgarishi kerak bo'lgan test fayli bor edi.

5. Peer bog'liqliklar

5.1 Kutubxona "React 18 gacha" desa

React'ni yangilagach eng ko'p uchraydigan to'siq — React'ga bog'liq kutubxonalar. Ular package.json da peerDependencies yozadi (package.json II): "men qaysi React bilan ishlayman". Buyurtma panelida eski drag-and-drop kutubxonasi bor — react-beautiful-dnd@13.1.1. Uning peer'i: react@"^16.8.5 || ^17.0.0 || ^18.0.0". 19 ro'yxatda yo'q.

Biz buni sinov papkasida haqiqiy npm 11.19.0 bilan sinadik. Ikki holat, ikki xil natija.

5.2 Mavjud loyihada yangilash — ogohlantirish

node_modules da React 18 o'rnatilgan, Sardor yangilaydi:

bash
npm install react@19.3.0 react-dom@19.3.0
text
npm warn ERESOLVE overriding peer dependency
npm warn While resolving: bahor-menyu@1.0.0
npm warn Found: react@18.3.1
npm warn node_modules/react
npm warn   peer react@"^16.8.5 || ^17.0.0 || ^18.0.0" from react-beautiful-dnd@13.1.1
npm warn   node_modules/react-beautiful-dnd
npm warn     react-beautiful-dnd@"13.1.1" from the root project
…
added 2 packages, removed 2 packages, and changed 3 packages in 2s

Chiqishda Found: react@18.3.1 (o'rnatilgani) va peer react@"…" (kutubxona talabi) qatorlarini solishtiring — 19 talabda yo'q. Lekin oxirgi qatorga qarang: added …, changed ….

O'rnatildi! Ekranda o'nlab sariq warn qatori bo'ladi, oxirida esa muvaffaqiyat. Ko'p dasturchi shu yerda to'xtaydi. Lekin daraxt endi noto'g'ri — npm ls buni ochiq aytadi:

bash
npm ls react
text
bahor-menyu@1.0.0
+-- react-beautiful-dnd@13.1.1
| +-- react-redux@7.2.9
| | `-- react@19.3.0 deduped invalid: "^16.8.5 || ^17.0.0 || ^18.0.0" from node_modules/react-beautiful-dnd, …
| +-- react@19.3.0 deduped invalid: "^16.8.5 || ^17.0.0 || ^18.0.0" from node_modules/react-beautiful-dnd
…
`-- react@19.3.0 invalid: "^16.8.5 || ^17.0.0 || ^18.0.0" from node_modules/react-beautiful-dnd

npm error code ELSPROBLEMS
npm error invalid: react@19.3.0 …\node_modules\react

Qatorlar qisqartirildi (to'liq yo'llar o'rniga …). invalid — "o'rnatilgan versiya talabga mos emas". Kutubxona ichida react-redux@7.2.9 ham bor — u ham faqat 18 gacha va'da beradi.

5.3 Toza o'rnatish — xato

Endi hamkasbingiz repo'ni yangi klonladi (yoki CI npm ci qildi). package.json da allaqachon react@^19.3.0:

text
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error While resolving: bahor-menyu@1.0.0
npm error Found: react@19.3.0
npm error node_modules/react
npm error   react@"^19.3.0" from the root project
npm error Could not resolve dependency:
npm error peer react@"^16.8.5 || ^17.0.0 || ^18.0.0" from react-beautiful-dnd@13.1.1
npm error node_modules/react-beautiful-dnd
npm error   react-beautiful-dnd@"13.1.1" from the root project
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.

"Bog'liqlik daraxtini hal qilib bo'lmadi… Yuqoridagi ziddiyatni tuzating yoki --force yoki --legacy-peer-deps bilan qayta urining — noto'g'ri (va ehtimol buzilgan) yechimni qabul qilish uchun." Sardorning kompyuterida hammasi ishlaydi, hamkasbida — o'rnatilmaydi. Klassik "menda ishlaydi" holati.

flowchart LR
  A["Sardor: npm install react@19"] --> B["warn, o'rnatildi"]
  B --> C["npm ls: invalid"]
  D["Hamkasb: toza npm install"] --> E["ERESOLVE, to'xtadi"]
  B -.->|"git push"| D

Maslahat: Katta yangilashdan keyin node_modules va package-lock.json ni o'chirib, toza npm install qiling — yoki npm ci. Shunda hamkasbingiz ko'radigan xatoni birinchi bo'lib siz ko'rasiz.

5.4 Nima qilish kerak

Yo'l Qachon Xavfi
Kutubxonani yangilash yangi versiyasi 19 ni qo'llasa yo'q, eng yaxshisi
Almashtirish kutubxona tashlab ketilgan ish hajmi
overrides (package.json) yangilanishi kutilyapti, siz sinab ko'rdingiz kutubxona haqiqatan buzilishi mumkin
--legacy-peer-deps deyarli hech qachon ziddiyatni yashiradi, keyingi o'rnatishda ham kerak

react-beautiful-dnd bizning sinovda o'zi aytdi: npm warn deprecated react-beautiful-dnd@13.1.1: react-beautiful-dnd is now deprecated. Demak, yangilanmaydi — almashtirish kerak (masalan, Drag and drop: dnd-kit). Avval npm outdated va kutubxonaning CHANGELOG'ini ko'ring (Bog'liqliklarni yangilash strategiyasi).

overrides faqat ongli qaror bilan: "kutubxona 19 da ishlashini o'zim tekshirdim". Sababi va sanasi bilan izoh yozing — keyinchalik kimdir uni olib tashlashi uchun:

json
{
  "overrides": {
    "react-beautiful-dnd": {
      "react": "$react",
      "react-dom": "$react-dom"
    }
  }
}

"$react" — "loyihaning o'z react versiyasini ishlat" degani. overrides chuqur — Begona paketni tuzatish darsida.

6. Yangilashdan keyin tekshiruv

Codemod va npm install tugadi. Endi — Bog'liqliklarni yangilash strategiyasi darsidagi ro'yxat, React'ga moslangan:

  1. git grep — olib tashlangan API'lar qolmadimi («Diff'ni o'qish» bo'limidagi «Diqqat» bloki).
  2. npx tsc -b — turlar toza (tsconfig frontend loyihada).
  3. npm run lint — React Hooks qoidalari ham (ESLint II).
  4. npm test — unit va komponent testlari.
  5. npm run dev — StrictMode ostida ilovani qo'lda aylanish, konsol toza bo'lsin.
  6. Build va e2e — vazifalar dagi 159 brauzer tekshiruvi kabi.

React 19 da yana bir xulq o'zgardi: render xatosi endi qayta tashlanmaydi, window.onerror ga emas, createRoot ning onUncaughtError iga keladi (React ilovani debug qilish). Xato kuzatish xizmati (Sentry kabi) window.onerror ga tayangan bo'lsa — ulanishini yangilang.

Tekshirib ko'ring: Barcha testlar o'tdi. defaultProps muammosi qolmaganiga ishonsa bo'ladimi?

Javob

Yo'q, faqat test aynan o'sha standart qiymatni tekshirgan bo'lsa. Ko'p testlar "komponent chizildimi" ni tekshiradi, "rangi yashilmi" ni emas. Shuning uchun git grep -n "defaultProps" — majburiy qadam: u test qamrovidan qat'i nazar hamma joyni ko'rsatadi.

7. Vazifalar qadami: audit (commit yo'q)

vazifalar React 19 da yaratilgan — kanonda bu dars uchun qadam yo'q (QADAMLAR.md: "#15 — o'qish/bilim"). Lekin auditni o'zimizda ham bajaramiz — bu tekshiruvning o'zi mashq:

bash
git grep -nE -e "ReactDOM\.render|findDOMNode|propTypes" \
  -e "defaultProps| ref=\"|test-utils|useFormState" -- src tekshiruv

Kanon v8 da natija — bo'sh (biz sinov/18/vazifalar-v8 da tekshirdik). Bitta yaqin topilma bor: AmalTugmasi.tsx dagi izoh — // React 19: ref — oddiy prop (forwardRef shart emas, 17/#34). forwardRef React 19 da hali ishlaydi, lekin endi kerak emas (useRef II). Biz uni boshidan ishlatmaganmiz.

package.json da ham hammasi aniq: react va react-dom — 19.3.0, @types/react — 19.3.0, runtime bog'liqliklar faqat uchta (react, react-dom, web-vitals). Peer ziddiyat yo'q.

8. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
TypeError: … render is not a function, oq ekran ReactDOM.render createRoot(el).render(<App />)
Expected ref to be a function, an object returned by React.createRef()… string ref ref callback yoki createRef
qiymat undefined, xato yo'q funksiyadagi defaultProps standart parametr
TS2503: Cannot find namespace 'JSX'. global JSX olib tashlandi import type { JSX } from "react"
TS2554: Expected 1 arguments, but got 0. (useRef) useRef argumentsiz useRef<T>(undefined) yoki (null)
ERESOLVE unable to resolve dependency tree kutubxona peer'i 18 gacha yangilash, almashtirish yoki overrides
.jsx faylda interface PropTypes codemod'i .tsx ga o'tkazish yoki qo'lda

9. Mashqlar

Mashqlar kurs/mashqlar/18/15-react-19/ da. Har yechimni «Ishga tushir» bilan sinang.

1-mashq (oson): nima bilan almashadi?

  • ReactDOM.render(<App />, el) → createRoot(el).(<App />)
  • ReactDOM.unmountComponentAtNode(el) → root.()
  • import { act } from "react-dom/test-utils" → import { act } from ""
  • Funksiyadagi Badge.defaultProps = { size: 2 } → function Badge({ size = })
Yechim

render, unmount, react, 2. Birinchi ikkitasi bitta naqsh: endi DOM element bilan ishlaydigan funksiyalar emas, createRoot qaytargan ildiz obyektining metodlari. act — testlarda ham react-dom emas, react ning o'zidan. Standart qiymat — JavaScript'ning standart parametri, React'ning maxsus xususiyati emas.

2-mashq (o'rta): rangsiz narx

React 19 ga o'tgach, menyu kartasida narxdan keyin valyuta yo'qoldi. Konsolda ogohlantirish yo'q. Tuzating — ekran Osh: 35000 so'm bo'lsin:

jsx
function Price({ dish, amount, currency }) {
  return (
    <p>
      {dish}: {amount} {currency}
    </p>
  );
}
Price.defaultProps = { currency: "so'm" };

function App() {
  return <Price dish="Osh" amount={35000} />;
}

Ekranda:

text
Osh: 35000
Yechim
jsx
function Price({ dish, amount, currency = "so'm" }) {
  return (
    <p>
      {dish}: {amount} {currency}
    </p>
  );
}

function App() {
  return <Price dish="Osh" amount={35000} />;
}

Ekranda:

text
Osh: 35000 so'm

Price.defaultProps qatori butunlay o'chirildi — React 19 uni baribir o'qimaydi, qoldirish keyingi o'quvchini chalg'itadi. Standart parametr faqat qiymat undefined bo'lganda ishlaydi: currency={null} berilsa, null qoladi. defaultProps ham aynan shunday ishlardi.

3-mashq (qiyin): string ref'siz qidiruv

Eski class komponent qidiruv maydoniga fokus qo'yadi va qiymatni o'qiydi. React 19 da u chizilmaydi (string ref). Uni createRef bilan tuzating (Class komponentlarni o'qish darsida ko'rgansiz): this.input = createRef() — konstruktor o'rniga class maydoni, keyin ref={this.input} va this.input.current. «Qidirish» bosilganda konsolga qidiruv: osh chiqsin.

jsx
import { Component } from "react";

class Search extends Component {
  handleClick = () => {
    console.log("qidiruv:", this.refs.query.value);
  };
  render() {
    return (
      <div>
        <input ref="query" defaultValue="osh" />
        <button onClick={this.handleClick}>Qidirish</button>
      </div>
    );
  }
}

function App() {
  return <Search />;
}
Yechim
jsx
import { Component, createRef } from "react";

class Search extends Component {
  input = createRef();
  handleClick = () => {
    console.log("qidiruv:", this.input.current.value);
  };
  render() {
    return (
      <div>
        <input ref={this.input} defaultValue="osh" />
        <button onClick={this.handleClick}>Qidirish</button>
      </div>
    );
  }
}

function App() {
  return <Search />;
}

Konsolda:

text
qidiruv: osh

createRef() — { current: null } obyekti; React commit'da unga DOM elementni yozadi. this.refs lug'ati endi kerak emas. Funksiya komponentga o'tkazsangiz — useRef(null) (useRef II); codemod esa ref callback yozadi. Uchala yo'l ham React 19 da to'g'ri.

4-mashq: vazifalar auditi

vazifalar papkasida «Vazifalar qadami» dagi git grep buyrug'ini ishga tushiring. Keyin npm ls react qiling: invalid yoki UNMET PEER bormi? Va npm outdated — qaysi paketlarning yangi versiyasi bor? Commit qilmang.

Yechim

git grep — bo'sh chiqishi kerak (kanonda shunday). npm ls react — react@19.3.0 daraxtda bir necha joyda deduped bilan, invalid yo'q: runtime bog'liqliklar faqat react, react-dom, web-vitals. npm outdated natijasi vaqtga bog'liq — siz o'qiyotganingizda yangi versiyalar chiqqan bo'lishi mumkin. Har biri uchun Bog'liqliklarni yangilash strategiyasi darsidagi qaror: patch/minor — CHANGELOG bilan, major — alohida branch va shu darsdagi tartib.

10. Real ishda

  • Legacy loyihalar: O'zbekistondagi ko'p kompaniya va davlat tizimlarida React 16–18 dagi kod ishlaydi. "React 19 ga ko'chirish" — junior/middle dasturchiga beriladigan tipik birinchi katta vazifa.
  • Bosqichli yangilash: katta loyihada React 18.3 bir necha hafta turadi — har jamoa o'z modulidagi ogohlantirishlarni tozalaydi.
  • Kutubxona tanlash: yangi kutubxona qo'shishdan oldin uning peer'ini va oxirgi chiqish sanasini tekshirish — yangilashdagi og'riqning yarmini oldini oladi.
  • Intervyu savollari: "React 19 da nima olib tashlandi?", "defaultProps nega xavfli?", "Peer dependency nima va ERESOLVE ni qanday hal qilasiz?", "--legacy-peer-deps nega yomon?".

Xulosa

  • React 19 da ReactDOM.render/hydrate/findDOMNode/unmountComponentAtNode yo'q — createRoot, hydrateRoot, ref.
  • String ref xato tashlaydi; funksiyadagi defaultProps va propTypes esa jim e'tiborsiz — eng xavflisi shu.
  • Tartib: 18.3 (ogohlantirishlar) → 19 + codemod → diff'ni o'qish → git grep, tsc, test, e2e.
  • Codemod ishning katta qismini qiladi, lekin bizning sinovda .jsx ga TS yozdi, defaultProps va .jsx test faylini o'tkazib yubordi.
  • Peer ziddiyat: mavjud loyihada — ogohlantirish va invalid, toza o'rnatishda — ERESOLVE. Yechim — yangilash yoki almashtirish, --legacy-peer-deps emas.

Keyingi dars: Render va commit: React ekranni qanday yangilaydi — trigger, render, commit va paint: qayta render nega DOM o'zgarishini anglatmaydi.

Manbalar

  • React 19 Upgrade Guide (2024-04-25) — react.dev/blog/2024/04/25/react-19-upgrade-guide
  • React 19 e'loni (2024-12-05) — react.dev/blog/2024/12/05/react-19
  • codemod CLI 1.18.3, react-19-migration-recipe — codemod.com registri (sinov: 2026-10-13)
  • types-react-codemod 3.5.3 — github.com/eps1lon/types-react-codemod
  • npm: peerDependencies, overrides — docs.npmjs.com/cli/configuring-npm/package-json
  • Sinov: npm 11.19.0, Node 24.21.0, react-beautiful-dnd@13.1.1 (2026-10-13)
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
React versiyasini yangilash: 18 dan 19 ga — olib tashlangan API'lar, codemod va peer xatolari — IlmHamroh