Kā novērst kļūdu “Target container is not a DOM element” React 18

Svarīgākais risinājums ir šāds: pārliecinieties, ka vērtība, ko nododat funkcijai createRoot(), ir reāls DOM elements, kas jau eksistē. React 18 standarta klienta ieejas punkts izskatās šādi:

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

const container = document.getElementById('root');

if (!container) {
  throw new Error('Root element not found');
}

const root = createRoot(container);
root.render(<App />);

Ja document.getElementById('root') atgriež null, vai ja nejauši nododat React elementu, piemēram, <App />, funkcijai createRoot(), React nevar izveidot sakni un var ziņot par kļūdu “Target container is not a DOM element.” React oficiālā createRoot problēmu novēršanas dokumentācija definē šo kļūdu tieši šādos vārdos: vērtība, kas nodota createRoot, nav DOM mezgls.

Šis ceļvedis sākas ar šo visbiežāk sastopamo cēloni, pēc tam aptver laika problēmas, React 18 migrācijas kļūdas, servera renderēšanu, portālus, TypeScript un testēšanas vides, lai jūs varētu apstāties, kad sasniedzat jūsu lietotnei atbilstošo gadījumu.

1. solis: Pierādiet, ko patiesībā nododat funkcijai createRoot()

Pirms konfigurācijas maiņas, reģistrējiet konteineru:

const container = document.getElementById('root');
console.log(container);

const root = createRoot(container);

Ja konsolē tiek izvadīts null, React nav tā daļa, kas pirmā neizdevās. Pārlūks neatrada elementu ar šo ID brīdī, kad jūsu kods tika izpildīts. React oficiālā problēmu novēršanas sadaļa norāda uz ID neatbilstību un izpildi pirms DOM mezgla eksistences kā biežiem iemesliem.

Ja konsolē tiek izvadīts kaut kas līdzīgs <div id="root"></div>, tad konteiners eksistē, un jums vajadzētu pāriet uz React API, SSR, portāla vai vides pārbaudēm zemāk.

Attiecas uz: gadījumiem, kad kļūda parādās uzreiz lietotnes starta laikā, īpaši failos main.jsx, index.jsx vai index.tsx.

Darbība: nespēlējiet minējumus. Reģistrējiet precīzo vērtību, kas nodota funkcijai createRoot(). Ja tā ir null, novērsiet iemeslu, kāpēc DOM meklēšana neizdevās, pirms pieskaraties komponentu kodam.

AI ģenerēta koda redaktora ilustrācija, kurā redzama React kļūda Target container is not a DOM element
AI ģenerēta ilustrācija par React 18 konteinera kļūdu izstrādātāja konsolē. Tā nav ekrānuzņēmums no reālas lietotnes vai React DevTools.

2. solis: Saskaņojiet HTML ID ar JavaScript meklēšanu

Vienkāršākais reālās dzīves cēlonis ir neatbilstība starp jūsu HTML un JavaScript.

Jūsu HTML var saturēt:

<div id="app"></div>

bet jūsu React ieejas fails meklē:

document.getElementById('root')

Šiem nosaukumiem ir jāsakrīt. Vai nu mainiet marķējumu:

<div id="root"></div>

vai mainiet meklēšanu:

const container = document.getElementById('app');

React pašreizējā createRoot atsauce izmanto standarta piemēru document.getElementById('root'), bet root nav maģisks obligāts ID. Jebkurš reāls DOM elements var tikt izmantots kā saknes konteiners. Svarīgākais nosacījums ir tas, ka elements eksistē un meklēšana to atgriež.

Attiecas uz: gadījumiem, kad nesen mainījāt HTML veidni, migrējāt no Create React App uz Vite vai citu bundleru, ieguldat React esošā servera renderētā lapā vai pārdēvējāt montēšanas elementu.

Darbība: meklējiet projektā gan id="root", gan getElementById('root'). Ja projekts apzināti izmanto citu ID, panāciet, lai HTML un JavaScript sakristu.

AI ģenerēta koda redaktora ilustrācija, kurā izcelts div elements ar id root HTML failā
AI ģenerēta ilustrācija par atbilstošu id="root" montēšanas elementu. Tas ir konceptuāls koda redaktora skats, nevis ekrānuzņēmums no konkrēta ietvara veidnes.

3. solis: Izmantojiet React 18 saknes API pareizā secībā

React 18 ieviesa createRoot klienta API. Oficiālajā React 18 jaunināšanas ceļvedī ir parādīta migrācija no vecāka ReactDOM.render modeļa uz:

import { createRoot } from 'react-dom/client';

const container = document.getElementById('root');
const root = createRoot(container);
root.render(<App />);

Pārsteidzoši viegla kļūda ir samainīt vietām DOM konteineru un React komponentu:

// Nepareizi
createRoot(<App />);

React skaidri norāda to kā citu biežu cēloni kļūdai “Target container is not a DOM element”. createRoot() saņem DOM mezglu; root.render() saņem React mezglu.

Cita migrācijas kļūda ir mentāli pārnest React 17 parakstu un mēģināt nodot konteineru funkcijai root.render():

// Nepareizs mentālais modelis
root.render(<App />, container);

// Pareizi
const root = createRoot(container);
root.render(<App />);

React createRoot atsauce dokumentē root.render(reactNode) kā funkciju, kas saņem React mezglu, savukārt konteiners pieder pie createRoot(domNode).

TypeScript: nesajauciet nenulles apgalvojumu ar laika risinājumu

React 18 jaunināšanas ceļvedis parāda createRoot(container!) kā TypeScript formu. Izsaukuma zīme ir kompilācijas laika apgalvojums: tā pasaka TypeScript, ka jūs uzskatāt vērtību par nenullu. Tā nerada trūkstošu HTML elementu izpildes laikā.

Drošāks modelis, kad atkļūdojat, ir:

const container = document.getElementById('root');

if (container === null) {
  throw new Error('Expected #root to exist');
}

createRoot(container).render(<App />);

Tas rada noderīgāku lietotnei specifisku kļūdu, ja HTML un JavaScript izklīst.

Attiecas uz: gadījumiem, kad problēma parādījās React 17 → React 18 migrācijas laikā, pēc ieejas faila kopēšanas no cita projekta, vai tikai TypeScript būvējumos, kur ! tika pievienots, lai apklusinātu kompilatora brīdinājumu.

Darbība: pārbaudiet izsaukumu secību: DOM meklēšana → createRoot(container) → root.render(<App />). Atkļūdošanas laikā dodiet priekšroku eksplcitai null pārbaudei, nevis aklai container! apgalvošanai.

AI ģenerēta koda redaktora ilustrācija, kurā redzama null pārbaude pirms createRoot un root render React 18
AI ģenerēta ilustrācija par aizsargājošu React 18 starta modeli. Kods ir parādīts kā konceptuāls piemērs, nevis kā sagūstīta izvade no reāla projekta.

4. solis: Pārliecinieties, ka jūsu starta kods tiek izpildīts pēc mērķa elementa izveides

ID var būt perfekti uzrakstīts, bet joprojām atgriezt null, ja jūsu skripts tiek izpildīts pirms pārlūks ir parsējis elementu. React problēmu novēršanas dokumentācija īpaši brīdina, ka bundlera skripts nespēj redzēt DOM mezglus, kas parādās vēlāk HTML, ja izpilde notiek pārāk agri.

Tas galvenokārt attiecas uz pielāgotām HTML lapām un vecākām iegulšanas iestatījumiem. Bieži sastopams drošs izkārtojums ir novietot montēšanas elementu pirms skripta:

<body>
  <div id="root"></div>
  <script type="module" src="/src/main.jsx"></script>
</body>

Ja kontrolējat pielāgotu skriptu, kas var tikt izpildīts pirms parsēšanas pabeigšanas, cita aizsargājoša opcija ir gaidīt DOMContentLoaded:

function start() {
  const container = document.getElementById('root');
  if (!container) throw new Error('Root element not found');
  createRoot(container).render(<App />);
}

if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', start);
} else {
  start();
}

Nepievienojiet šo ietvaru automātiski katram React projektam. Mūsdienu bundleri un ietvari parasti pārvalda ieejas skriptu novietojumu un ielādes semantiku jūsu vietā. Ja standarta Vite, Next.js, Remix vai ietvara ģenerēta lietotne pēkšņi sāk rādīt šo kļūdu, vispirms meklējiet mainītu veidni, montēšanas ID, pielāgotu integrāciju vai kodu, kas darbojas ārpus paredzētās pārlūka ieejas punkta.

Attiecas uz: gadījumiem, kad tas pats ID eksistē gala HTML, bet meklēšana starta laikā joprojām ir null, īpaši manuāli saliktā HTML lapā, CMS veidnē, logrīka iegulumā vai trešās puses skripta integrācijā.

Darbība: pārbaudiet faktisko lapas avotu un izpildes secību. Pārliecinieties, ka montēšanas mezgls eksistē pirms koda, kas izsauc createRoot().

AI ģenerēta koda redaktora ilustrācija, kurā redzama DOMContentLoaded aizsardzība pirms React saknes izveides
AI ģenerēta ilustrācija par DOM gatavības aizsardzību pielāgotai React startēšanai. Tas nav obligāts modelis katrai React 18 lietotnei; izmantojiet to tikai tad, kad starta laiks patiešām ir problēma.

Ja jūsu lapa ir servera renderēta, izmantojiet hydrateRoot vietā

Ir svarīgs nosacījums, kurā derīgs DOM elements nav pietiekams, lai createRoot() būtu pareizais API. Ja konteiners jau satur HTML, ko serverī vai būvēšanas laikā ģenerējis React, React dokumentācija saka izmantot hydrateRoot() nevis createRoot().

import { hydrateRoot } from 'react-dom/client';
import App from './App';

const container = document.getElementById('root');

if (!container) {
  throw new Error('Root element not found');
}

hydrateRoot(container, <App />);

Iemesls atšķiras no mērķa konteinera kļūdas. createRoot() pārvalda klienta renderētu sakni un pirmajā renderēšanā notīra esošo HTML šajā saknē. hydrateRoot() piesien React HTML, ko serverī jau bija izveidojis React. Oficiālā createRoot dokumentācija to skaidri norāda kā servera renderēšanas slazdu.

Attiecas uz: gadījumiem, kad jums ir servera renderēts React HTML, statiska ģenerēšana, kas izdala React marķējumu, vai ietvars, kas hidrē HTML pārlūkā.

Darbība: “nelabojiet” SSR, aizstājot servera marķējumu ar tukšu konteineru. Izmantojiet ietvara hidrācijas ieejas punktu vai React hydrateRoot() pēc vajadzības.

Ja tas ir modāļa vai rīka padoma mērķis, jums var būt nepieciešams createPortal, nevis cita sakne

Dažreiz izstrādātāji redz trūkstošu konteineru, mēģinot renderēt modāli, rīka padomu, toast reģionu vai pārklājumu ārpus galvenās lietotnes koka. React dokumentācija saka, ka, ja vēlaties, lai JSX parādītos citur DOM, izmantojiet createPortal(), nevis veidojiet citu sakni tikai šim bērna UI.

import { createPortal } from 'react-dom';

function Modal({ children }) {
  const modalRoot = document.getElementById('modal-root');

  if (!modalRoot) return null;

  return createPortal(children, modalRoot);
}

Oficiālā createPortal dokumentācija saka, ka portāla mērķim jau ir jāeksistē. Tātad portāli var radīt saistītu konteinera problēmu klasi, ja modal-root trūkst, bet arhitektūras risinājums nav obligāti “izsaukt createRoot vēlreiz”.

Attiecas uz: gadījumiem, kad kļūdainais konteiners nav jūsu lietotnes galvenā sakne, bet gan pārklājuma mērķis vai mezgls, kas pārvaldīts ārpus komponenta parastās DOM pozīcijas.

Darbība: saglabājiet vienu parasto lietotnes sakni, ja vien jums patiešām nav nepieciešamas vairākas neatkarīgas saknes. Modāļa stila UI vienā React lietotnē dodiet priekšroku portālam uz esošu DOM mezglu.

Kas notiek, ja kļūda rodas tikai testos?

Tests var neizdoties tā paša fundamentālā iemesla dēļ: paredzētais konteiners nekad netika ievietots testa DOM. Ja jūsu tests manuāli izsauc createRoot(document.getElementById('root')), pārliecinieties, ka testa iestatījums patiešām izveido šo mezglu pirms renderēšanas.

beforeEach(() => {
  document.body.innerHTML = '<div id="root"></div>';
});

Tomēr daudzas React testēšanas bibliotēkas pārvalda konteinerus jūsu vietā. Ja jau izmantojat testēšanas ietvara render() palīgfunkciju, manuāla React saknes izveide var būt nevajadzīga un padarīt testa iestatījumus trauslākus.

Attiecas uz: gadījumiem, kad izstrāde pārlūkā darbojas, bet Jest, Vitest, JSDOM vai cita testēšanas vide met konteinera kļūdu.

Darbība: pārbaudiet testa DOM iestatījumus, nevis produkcijas index.html. Pārliecinieties, ka mezgls eksistē vidē, kurā kļūdainais kods patiesībā darbojas.

Kas notiek, ja dokuments nav pieejams?

Ja kods, kas izsauc document.getElementById(), tiek izpildīts serverī vai citā nepārlūka vidē, jums ir cita integrācijas problēma. React klienta API react-dom/client ir paredzēti renderēšanai pārlūka DOM mezglos. Servera renderēšana izmanto API no react-dom/server, un ietvari parasti atdala servera un klienta ieejas punktus.

Attiecas uz: gadījumiem, kad kļūda parādās servera puses renderēšanas laikā, Node būvēšanas solī vai kodā, kas kopīgs starp servera un pārlūka bundleriem.

Darbība: pārvietojiet tikai pārlūkam paredzēto saknes izveidi uz klienta ieejas punktu. Ja izmantojat ietvaru, sekojiet tā dokumentētajai klienta/servera robežai, nevis manuāli izsauciet createRoot() no kopīga servera koda.

Ātrās diagnostikas tabula

Ko jūs redzatIespējamais cēlonisLabākā nākamā pārbaude
console.log(container) ir nullID neatbilstība vai elements vēl nav klātSalīdziniet HTML ID un meklēšanu; pārbaudiet skripta laiku
HTML izmanto id="app", kods vaicā rootMontēšanas ID neatbilstībaPadariet abus nosaukumus identiskus
createRoot(<App />)React elements nodots tur, kur nepieciešams DOM mezglsNododiet DOM mezglu createRoot, pēc tam renderējiet <App />
Projekts joprojām izmanto ReactDOM.render pēc React 18 jaunināšanasVecs klienta APIMigrējiet uz createRoot, izmantojot React 18 jaunināšanas ceļvedi
Konteiners jau satur servera renderētu React HTMLNepareiza klienta inicializācijas APIIzmantojiet hydrateRoot
Neizdodas tikai modāļa/rīka padoma mērķisTrūkstošs portāla mērķis vai nevajadzīga papildu sakneIzmantojiet createPortal ar esošu DOM mezglu
Neizdodas tikai testiTesta DOM nekad neizveidoja mērķa elementuIzveidojiet konteineru testa iestatījumā vai izmantojiet testu bibliotēkas renderētāju

Gala pārbaude: apstipriniet labojumu, nevis slēpjiet kļūdu

Pēc izmaiņu veikšanas pārbaudiet starta ceļu šādā secībā:

  1. Atveriet lapu un pārbaudiet pārlūka konsoli. Mērķa konteinera kļūdai vajadzētu būt pazūdai.
  2. Izpildiet console.log(document.getElementById('root')) un pārliecinieties, ka tas izvada reālu elementu, nevis null.
  3. Pārliecinieties, ka importējat createRoot no react-dom/client React 18 klienta renderētā lietotnē.
  4. Pārliecinieties, ka DOM elements tiek nodots createRoot() un React komponents tiek nodots root.render().
  5. Ja lapa tika renderēta ar React serverī, pārliecinieties, ka klients izmanto hydrateRoot() vietā.
  6. Ja kļūdainais mērķis ir modālis vai rīka padoms, pārliecinieties, ka portāla mērķis eksistē pirms createPortal() izsaukšanas.

Nekonsiderējiet TypeScript nenulles apgalvojumu, opcionālo ķēdēšanu vai catch bloku kā pašu labojumu. Šīs tehnikas var apklusināt kļūdas ceļu, nepiegādājot DOM mezglu, ko React patiesībā nepieciešams. Ilgtspējīgs labojums ir panākt, lai lapas struktūra, inicializācijas API un izpildes laiks sakristu.

Parastai React 18 vienlapas lietotnei īsākais pareizais mentālais modelis ir: HTML izveido konteineru; JavaScript atrod šo konteineru; createRoot saņem konteineru; root.render saņem komponentu. Kad šīs četras daļas ir pareizā secībā, “Target container is not a DOM element” parasti pazūd pareizā iemesla dēļ.

Atstājiet komentāru

Kā novērst kļūdu "ENOSPC: sasniegts failu vērotāju sistēmas ierobežojums" operētājsistēmā Linux

Kā novērst kļūdu "ENOSPC: sasniegts failu vērotāju sistēmas ierobežojums" operētājsistēmā Linux

Novērsiet Linux ENOSPC failu vērotāja kļūdas, pārbaudot inotify ierobežojumus, atrodot procesus, kuros ir daudz vērotāja resursu, droši paaugstinot ierobežojumus un padarot izmaiņas pastāvīgas.

Kā novērst kļūdu “Tailwind CSS stili netiek atjaunināti” Vite React lietotnē

Kā novērst kļūdu “Tailwind CSS stili netiek atjaunināti” Vite React lietotnē

Novērsiet Tailwind CSS stilu neatjaunināšanu pakalpojumā Vite React, pārbaudot Tailwind v4 iestatījumus, CSS importēšanu, avota noteikšanu, dinamiskās klases, HMR un novecojušas kešatmiņas.

Kā novērst ModuleNotFoundError kļūdu: Python 3 nav moduļa ar nosaukumu “pip”

Kā novērst ModuleNotFoundError kļūdu: Python 3 nav moduļa ar nosaukumu “pip”

Novērsiet Python 3 ModuleNotFoundError kļūdu pip funkcijai operētājsistēmās Windows, macOS un Linux, izmantojot ensurepip, OS pakotnes, virtuālās vides un interpretētāja pārbaudes.

Kā GitHub SSH novērst kļūdu "Atļauja liegta (publiskā atslēga)"

Kā GitHub SSH novērst kļūdu "Atļauja liegta (publiskā atslēga)"

Novērsiet GitHub SSH atļaujas liegšanu (publiskā atslēga), pārbaudot resursdatoru, aktīvo SSH atslēgu, GitHub kontu, SSO autorizāciju, attālo URL un 22. porta piekļuvi.

Kā novērst kļūdu “Git Push noraidīts: nepārtīšana uz priekšu”, nezaudējot izmaiņas

Kā novērst kļūdu “Git Push noraidīts: nepārtīšana uz priekšu”, nezaudējot izmaiņas

Droši izlabojiet Git ne-ātrās pārtīšanas kļūdu. Aizsargājiet lokālo darbu, ielādējiet attālinātus izmaiņu izmaiņu ierakstus, izvēlieties apvienošanu vai atkārtotu bāzi, atrisiniet konfliktus un veiciet izmaiņu pārtīšanu, nezaudējot izmaiņas.

Kā novērst kļūdu "Nginx 502 Bad Gateway", veicot starpniekservera darbību ar Node.js

Kā novērst kļūdu "Nginx 502 Bad Gateway", veicot starpniekservera darbību ar Node.js

Izlabojiet Nginx 502 Bad Gateway kļūdas ar Node.js augšupējo resursu, pārbaudot lietotnes portu, NGINX žurnālus, proxy_pass adresi, konteineru tīklošanu, taimautus un atkārtotu ielādi.

Kā TypeScript labot kļūdu “Type 'null' nav piešķirams tipam”

Kā TypeScript labot kļūdu “Type 'null' nav piešķirams tipam”

Novērsta TypeScript kļūda “Tips 'null' nav piešķirams tipam”, izmantojot apvienošanas tipus, sašaurināšanu, noklusējuma vērtības un drošas apgalvojumus, izmantojot strictNullChecks.

Kā novērst kļūdu “Prisma Client has not been generated yet”

Kā novērst kļūdu “Prisma Client has not been generated yet”

Novērsiet Prisma Client ģenerēšanas kļūdu, pārbaudot savu ģeneratoru, shēmu, izvades ceļu, importus, versijas, monorepo iestatījumu un izvietošanas būvēšanas soļus.

Kā novērst kļūdu "ERR_MODULE_NOT_FOUND" Node.js ESM importā

Kā novērst kļūdu "ERR_MODULE_NOT_FOUND" Node.js ESM importā

Izlabojiet Node.js ERR_MODULE_NOT_FOUND kļūdu ESM, pārbaudot importēšanas ceļus, failu paplašinājumus, pakotņu instalēšanu, eksportēšanu, ESM režīmu un tīrās instalācijas.

Kā novērst SSL sertifikāta problēmu: Nevar iegūt vietējo izdevēja sertifikātu Git

Kā novērst SSL sertifikāta problēmu: Nevar iegūt vietējo izdevēja sertifikātu Git

Novērsiet Git kļūdu “nevar iegūt vietējo izdevēja sertifikātu”, identificējot uzticības aizmugurprogrammu, instalējot pareizo CA ķēdi un saglabājot SSL verifikāciju iespējotu.