Jak opravit chybu „Target container is not a DOM element“ v Reactu 18

Nejdůležitější oprava je tato: ujistěte se, že hodnota, kterou předáváte funkci createRoot(), je skutečný DOM element, který již existuje. V Reactu 18 vypadá běžný klientský vstupní bod takto:

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 />);

Pokud document.getElementById('root') vrátí null, nebo pokud omylem předáte React element, jako je <App />, funkci createRoot(), React nemůže vytvořit kořen a může hlásit chybu „Target container is not a DOM element.“ Dokumentace Reactu k řešení problémů s createRoot definuje tuto chybu přesně v těchto termínech: hodnota předaná funkci createRoot není DOM uzel.

Tato příručka začíná touto vysoce pravděpodobnou příčinou, poté se věnuje problémům s načasováním, chybám při migraci na React 18, serverovému vykreslování, portálům, TypeScriptu a testovacím prostředí, abyste mohli přestat, jakmile narazíte na případ, který odpovídá vaší aplikaci.

Krok 1: Ověřte, co skutečně předáváte funkci createRoot()

Než začnete měnit konfiguraci, zalogujte kontejner:

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

const root = createRoot(container);

Pokud konzola vypíše null, React není část, která selhala jako první. Prohlížeč nenašel element s tímto ID v okamžiku, kdy váš kód běžel. Oficiální sekce Reactu pro řešení problémů uvádí neshodu ID a spuštění před existencí DOM uzlu jako běžné důvody.

Pokud konzola vypíše něco jako <div id="root"></div>, pak kontejner existuje a měli byste přejít na níže uvedené kontroly React API, SSR, portálů nebo prostředí.

Platí, když: chyba se objeví okamžitě při spuštění aplikace, zejména v main.jsx, index.jsx nebo index.tsx.

Akce: nehádejte. Zalogujte přesnou hodnotu předanou funkci createRoot(). Pokud je null, opravte důvod, proč vyhledávání v DOM selhalo, než začnete sahat do kódu komponent.

Ilustrace generovaná AI v editoru kódu zobrazující chybu Reactu Target container is not a DOM element
Ilustrace generovaná AI chyby kontejneru v Reactu 18 ve vývojářské konzoli. Nejedná se o snímek obrazovky ze skutečné aplikace nebo React DevTools.

Krok 2: Srovnejte ID v HTML s vyhledáváním v JavaScriptu

Nejjednodušší příčina v reálném světě je neshoda mezi vaším HTML a JavaScriptem.

Vaše HTML může obsahovat:

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

zatímco váš vstupní soubor Reactu požaduje:

document.getElementById('root')

Tyto názvy se musí shodovat. Buď změňte markup:

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

nebo změňte vyhledávání:

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

Aktuální reference createRoot v Reactu používá standardní příklad document.getElementById('root'), ale root není magické povinné ID. Jako kořenový kontejner lze použít jakýkoli skutečný DOM element. Důležitou podmínkou je, že element existuje a že vyhledávání jej vrátí.

Platí, když: nedávno jste změnili HTML šablonu, migrovali z Create React App na Vite nebo jiný bundler, vložili React do existující serverově vykreslené stránky nebo přejmenovali montážní element.

Akce: prohledejte projekt pro id="root" i getElementById('root'). Pokud projekt záměrně používá jiné ID, ujistěte se, že HTML a JavaScript si odpovídají.

Ilustrace generovaná AI v editoru kódu zvýrazňující div s id root v HTML souboru
Ilustrace generovaná AI montážního elementu s odpovídajícím id="root". Jedná se o konceptuální pohled v editoru kódu, nikoli o snímek obrazovky konkrétní šablony frameworku.

Krok 3: Používejte React 18 root API ve správném pořadí

React 18 zavedl klientské API createRoot. Oficiální průvodce upgradem na React 18 ukazuje migraci ze staršího vzoru ReactDOM.render na:

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

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

Překvapivě snadná chyba je prohození rolí DOM kontejneru a React komponenty:

// Špatně
createRoot(<App />);

React to explicitně uvádí jako další běžnou příčinu chyby „Target container is not a DOM element“. Funkce createRoot() přijímá DOM uzel; funkce root.render() přijímá React uzel.

Další chybou při migraci je mentální přenesení signatury z Reactu 17 a pokus předat kontejner funkci root.render():

// Špatný mentální model
root.render(<App />, container);

// Správně
const root = createRoot(container);
root.render(<App />);

Reference createRoot v Reactu dokumentuje root.render(reactNode) jako přijímající React uzel, zatímco kontejner patří do createRoot(domNode).

TypeScript: nezaměňujte non-null aserci s opravou za běhu

Průvodce upgradem na React 18 ukazuje createRoot(container!) jako formu pro TypeScript. Vykřičník je aserce v době kompilace: říká TypeScriptu, že věříte, že hodnota není null. Nevytváří chybějící HTML element za běhu.

Bezpečnější vzor při ladění je:

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

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

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

To vytvoří užitečnější chybu specifickou pro aplikaci, pokud se HTML a JavaScript rozjedou.

Platí, když: problém se objevil během migrace z Reactu 17 na React 18, po zkopírování vstupního souboru z jiného projektu, nebo pouze v TypeScript sestaveních, kde bylo přidáno ! k umlčení varování kompilátoru.

Akce: ověřte posloupnost volání: vyhledání v DOM → createRoot(container) → root.render(<App />). Při ladění preferujte explicitní kontrolu null před slepým asertováním container!.

Ilustrace generovaná AI v editoru kódu zobrazující kontrolu null před createRoot a root render v Reactu 18
Ilustrace generovaná AI defenzivního vzoru pro spuštění Reactu 18. Kód je zobrazen jako konceptuální příklad, nikoli jako zachycený výstup ze skutečného projektu.

Krok 4: Ujistěte se, že váš spouštěcí kód běží až po existenci cílového elementu

ID může být dokonale napsáno a stále vrátit null, pokud váš skript běží dříve, než prohlížeč element zpracoval. Dokumentace Reactu pro řešení problémů specificky varuje, že skript balíčku nemůže vidět DOM uzly, které se objevují později v HTML, pokud dojde k provedení příliš brzy.

To je relevantní hlavně pro vlastní HTML stránky a starší nastavení vložení. Běžné bezpečné rozložení je umístit montážní element před skript:

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

Pokud kontrolujete vlastní skript, který může běžet před dokončením zpracování, další obrannou možností je počkat na 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();
}

Nepřidávejte tento obal automaticky do každého React projektu. Moderní bundlery a frameworky obvykle spravují umístění vstupního skriptu a sémantiku načítání za vás. Pokud standardní aplikace Vite, Next.js, Remix nebo generovaná frameworkem náhle začne hlásit tuto chybu, nejprve hledejte změněnou šablonu, montážní ID, vlastní integraci nebo kód běžící mimo očekávaný klientský vstupní bod prohlížeče.

Platí, když: stejné ID existuje ve finálním HTML, ale vyhledávání je stále null během spouštění, zejména v ručně sestavené HTML stránce, CMS šabloně, vložení widgetu nebo integraci skriptu třetí strany.

Akce: prozkoumejte skutečný zdroj stránky a pořadí provedení. Ujistěte se, že montážní uzel existuje před kódem, který volá createRoot().

Ilustrace generovaná AI v editoru kódu zobrazující ochranu DOMContentLoaded před vytvořením React kořene
Ilustrace generovaná AI ochrany připravenosti DOM pro vlastní bootstrap Reactu. Nejedná se o povinný vzor pro každou aplikaci React 18; použijte ji pouze tehdy, když je načasování spuštění skutečně problém.

Pokud je vaše stránka serverově vykreslována, použijte hydrateRoot místo toho

Existuje důležitá podmínka, kde platný DOM element nestačí k tomu, aby createRoot() bylo správné API. Pokud kontejner již obsahuje HTML vygenerované Reactem na serveru nebo v době sestavení, dokumentace Reactu říká, že místo createRoot() máte použít hydrateRoot().

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 />);

Důvod je odlišný od chyby cílového kontejneru. createRoot() spravuje klientsky vykreslený kořen a při prvním vykreslení vymaže existující HTML uvnitř tohoto kořene. hydrateRoot() připojuje React k HTML, které již bylo vyprodukováno Reactem na serveru. Oficiální dokumentace createRoot to explicitně uvádí jako úskalí serverového vykreslování.

Platí, když: máte serverově vykreslené React HTML, statickou generaci, která emituje React markup, nebo framework, který hydratací připojuje React k HTML v prohlížeči.

Akce: neopravujte SSR nahrazením serverového markupu prázdným kontejnerem. Použijte hydratační vstupní bod frameworku nebo React hydrateRoot() podle potřeby.

Pokud je toto cíl pro modální okno nebo tooltip, možná potřebujete createPortal – ne další kořen

Někdy vývojáři vidí chybějící kontejner při pokusu vykreslit modální okno, tooltip, oblast toastu nebo překryv mimo hlavní strom aplikace. Dokumentace Reactu říká, že když chcete, aby se JSX objevil jinde v DOM, použijte createPortal() místo vytváření dalšího kořene jen pro toto podřízené UI.

import { createPortal } from 'react-dom';

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

  if (!modalRoot) return null;

  return createPortal(children, modalRoot);
}

Oficiální dokumentace createPortal říká, že cíl portálu musí již existovat. Portály tedy mohou způsobit související třídu problémů s kontejnerem, pokud chybí modal-root, ale architektonická oprava není nutně „zavolejte znovu createRoot“.

Platí, když: selhávající kontejner není hlavní kořen vaší aplikace, ale cíl překryvu nebo uzel spravovaný mimo normální pozici komponenty v DOM.

Akce: udržujte jeden normální kořen aplikace, pokud opravdu nepotřebujete více nezávislých kořenů. Pro UI ve stylu modálních oken v rámci stejné React aplikace preferujte portál do existujícího DOM uzlu.

Co když k chybě dochází pouze v testech?

Test může selhat ze stejného základního důvodu: očekávaný kontejner nikdy nebyl vložen do testovacího DOM. Pokud váš test ručně volá createRoot(document.getElementById('root')), ujistěte se, že nastavení testu skutečně vytvoří tento uzel před vykreslením.

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

Mnoho testovacích knihoven pro React však spravuje kontejnery za vás. Pokud již používáte pomocníka render() testovacího frameworku, ruční vytváření React kořene může být zbytečné a může učinit nastavení testu křehčím.

Platí, když: vývoj funguje v prohlížeči, ale Jest, Vitest, JSDOM nebo jiné testovací prostředí vyhazuje chybu kontejneru.

Akce: prozkoumejte nastavení DOM testu, nikoli produkční index.html. Potvrďte, že uzel existuje v prostředí, kde selhávající kód skutečně běží.

Co když není dostupný objekt document?

Pokud kód volající document.getElementById() běží na serveru nebo v jiném prostředí mimo prohlížeč, máte jiný problém s integrací. Klientská API Reactu v react-dom/client jsou určena k vykreslování do DOM uzlů prohlížeče. Serverové vykreslování používá API z react-dom/server a frameworky obvykle oddělují serverové a klientské vstupní body.

Platí, když: chyba se objevuje během serverového vykreslování, kroku sestavení Node nebo kódu sdíleného mezi serverovými a klientskými balíčky.

Akce: přesuňte vytváření kořene pouze pro prohlížeč do klientského vstupního bodu. Pokud používáte framework, řiďte se jeho zdokumentovanou hranicí server/klient místo ručního volání createRoot() ze sdíleného serverového kódu.

Rychlá tabulka diagnostiky

Co vidítePravděpodobná příčinaNejlepší další kontrola
console.log(container) je nullNeshoda ID nebo element ještě není přítomenPorovnejte HTML ID a vyhledávání; prozkoumejte načasování skriptu
HTML používá id="app", kód dotazuje rootNeshoda montážního IDUčiňte oba názvy identickými
createRoot(<App />)React element předán tam, kde je vyžadován DOM uzelPředejte DOM uzel funkci createRoot, poté vykreslete <App />
Projekt stále používá ReactDOM.render po upgradu na React 18Legacy klientské APIMigrujte na createRoot pomocí průvodce upgradem na React 18
Kontejner již obsahuje serverově vykreslené React HTMLŠpatná inicializační API klientaPoužijte hydrateRoot
Selhal pouze cíl modálního okna/tooltipuChybějící cíl portálu nebo zbytečný další kořenPoužijte createPortal s existujícím DOM uzlem
Selhávají pouze testyTestovací DOM nikdy nevytvořil cílový elementVytvořte kontejner v nastavení testu nebo použijte vykreslovač testovací knihovny

Finální ověření: potvrďte opravu místo skrývání chyby

Po provedení změny ověřte cestu spouštění v tomto pořadí:

  1. Otevřete stránku a prozkoumejte konzoli prohlížeče. Chyba cílového kontejneru by měla být pryč.
  2. Spusťte console.log(document.getElementById('root')) a potvrďte, že vypíše skutečný element, nikoli null.
  3. Potvrďte, že importujete createRoot z react-dom/client v klientsky vykreslené aplikaci React 18.
  4. Potvrďte, že DOM element je předán funkci createRoot() a React komponenta je předána funkci root.render().
  5. Pokud byla stránka vykreslena Reactem na serveru, potvrďte, že klient místo toho používá hydrateRoot().
  6. Pokud selhávajícím cílem je modální okno nebo tooltip, potvrďte, že cíl portálu existuje před voláním createPortal().

Nepovažujte aserci non-null v TypeScriptu, volitelné řetězení nebo blok catch za samotnou opravu. Tyto techniky mohou umlčet cestu chyby bez dodání DOM uzlu, který React skutečně potřebuje. Trvalá oprava spočívá v tom, že struktura stránky, inicializační API a načasování provedení budou souhlasit.

Pro normální jednostránkovou aplikaci React 18 je nejkratší správný mentální model: HTML vytvoří kontejner; JavaScript najde tento kontejner; createRoot přijme kontejner; root.render přijme komponentu. Jakmile jsou tyto čtyři části ve správném pořadí, chyba „Target container is not a DOM element“ obvykle zmizí z toho správného důvodu.

Zanechat komentář

Jak opravit chybu „PyTorch CUDA Out of Memory“ během trénování modelu

Jak opravit chybu „PyTorch CUDA Out of Memory“ během trénování modelu

Opravte chyby nedostatečné paměti CUDA v PyTorch pomocí praktického postupu: měřte paměť GPU, zmenšete pracovní množinu, použijte AMP a akumulaci gradientů, ukládejte aktivace (checkpointing) a laděte alokátor pouze v případě potřeby.

Jak opravit chybějící hlavičku CORS Access-Control-Allow-Origin v Express.js

Jak opravit chybějící hlavičku CORS Access-Control-Allow-Origin v Express.js

Opravte chybu CORS s chybějící hlavičkou Access-Control-Allow-Origin v Express.js diagnostikou původu, bezpečnou konfigurací cors, zpracováním preflight požadavků a ověřením hlaviček.

Jak opravit chybu „Cannot read properties of undefined (reading 'map')“ v Reactu

Jak opravit chybu „Cannot read properties of undefined (reading 'map')“ v Reactu

Opravte chybu Reactu „Cannot read properties of undefined (reading 'map')“ vysledováním nedefinované hodnoty, opravou stavu a dat z API a přidáním bezpečných ochranných mechanismů při vykreslování.

Jak opravit chybu Module Not Found: Nelze vyřešit fs ve Webpacku

Jak opravit chybu Module Not Found: Nelze vyřešit fs ve Webpacku

Opravte chybu Webpacku „Nelze vyřešit 'fs'“ správným řešením: přesuňte kód pouze pro Node na server, použijte závislost bezpečnou pro prohlížeč, nastavte fs:false pouze u volitelných funkcí nebo správně cílte na Node.

Jak opravit chybu „Supabase API Key Not Found“ v proměnných prostředí

Jak opravit chybu „Supabase API Key Not Found“ v proměnných prostředí

Opravte chybějící klíče API Supabase v Next.js, Vite, Node, nasazeních a Edge Functions. Použijte aktuální názvy publikovatelných/secret klíčů, správné soubory env a bezpečné kroky ověření.

Jak opravit chybu „Flutter Command Not Found“ (cesta) v systému macOS

Jak opravit chybu „Flutter Command Not Found“ (cesta) v systému macOS

Opravte chybu „flutter: command not found“ v systému macOS nalezením SDK Flutter, přidáním složky bin do proměnné PATH, znovu načtením Zsh a ověřením nastavení.

Jak opravit chybu „Port 8080 je již používán“ v terminálu na Windows, macOS a Linuxu

Jak opravit chybu „Port 8080 je již používán“ v terminálu na Windows, macOS a Linuxu

Opravte chybu „Port 8080 je již používán“ nalezením procesu, který port vlastní, jeho bezpečným zastavením, řešením problémů s Dockerem nebo výběrem nového portu.

Jak opravit chybu Django „ImproperlyConfigured: The SECRET_KEY Setting Must Not Be Empty“

Jak opravit chybu Django „ImproperlyConfigured: The SECRET_KEY Setting Must Not Be Empty“

Opravte chybu Django SECRET_KEY must not be empty kontrolou aktivního modulu nastavení, proměnných prostředí, generování klíče a konfigurace produkčního prostředí.

Jak opravit chybu „Connection Refused“ u PostgreSQL na localhostu portu 5432

Jak opravit chybu „Connection Refused“ u PostgreSQL na localhostu portu 5432

Opravte chybu „connection refused“ u PostgreSQL na localhost:5432 kontrolou stavu serveru, nástroje pg_isready, naslouchání na portu, souboru postgresql.conf, mapování Dockeru a ověřování.

Jak opravit chybu „Hydration failed because the initial UI does not match“

Jak opravit chybu „Hydration failed because the initial UI does not match“

Opravte nesoulad hydratace v Reactu nebo Next.js tak, aby se serverové HTML shodovalo s prvním vykreslením na klientovi, a poté ověřte výsledek ve vývojovém i produkčním prostředí.