createRoot

createRoot дозволяє створити корінь для відображення React-компонентів всередині DOM-вузла браузера.

const root = createRoot(domNode, options?)

Посилання

createRoot(domNode, options?)

Виклик createRoot для створення кореня React для відображення вмісту всередині DOM-елемента браузера.

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

const domNode = document.getElementById('root');
const root = createRoot(domNode);

React створить корінь для domNode і візьме на себе керування DOM всередині нього. Після того, як ви створили корінь, вам потрібно викликати root.render, щоб відобразити React-компонент всередині нього:

root.render(<App />);

Додаток, повністю зібраний з React, зазвичай має лише один createRoot виклик кореневого компонента. Сторінка, яка використовує "посипання" React для частин сторінки, може мати стільки окремих коренів, скільки потрібно.

Дивіться більше прикладів нижче.

Параметри

  • domNode: Елемент DOM. React створить корінь для цього DOM-елемента і дозволить вам викликати функції в корені, такі як render для відображення відрендереного вмісту React.

  • опція опцій: Об'єкт з опціями для цього кореня React.

    • optional onRecoverableError: Зворотний виклик, що виконується, коли React автоматично відновлюється після помилок.
    • .
    • optional identifierPrefix: Рядковий префікс, який React використовує для ідентифікаторів, згенерованих useId. Корисно для уникнення конфліктів при використанні декількох коренів на одній сторінці.

Повернення

createRoot повертає об'єкт з двома методами: render та unmount.

Застереження

  • Якщо ваш застосунок рендериться на сервері, використання createRoot() не підтримується. Замість цього використовуйте hydrateRoot().
  • Ймовірно, у вашому застосунку буде лише один виклик createRoot. Якщо ви використовуєте фреймворк, він може виконати цей виклик за вас.
  • Якщо ви хочете відрендерити фрагмент JSX в іншій частині DOM-дерева, яка не є нащадком вашого компонента (наприклад, модальне вікно або підказку), використовуйте createPortal замість createRoot.

root.render(reactNode)

Виклик root.render для відображення фрагменту JSX ("вузол React") у DOM-вузол браузера React root.

root.render(<App />);

React відобразить <App /> у корені і візьме на себе керування DOM всередині нього.

Дивіться більше прикладів нижче.

Параметри

  • reactNode: Вузол React-вузла, який ви хочете відобразити. Зазвичай це буде фрагмент JSX на кшталт <App />, але ви також можете передати React-елемент, побудований за допомогою createElement(), рядок, число, null або undefined.

Повернення

root.render повертає undefined.

Застереження

  • При першому виклику root.render React очистить весь існуючий HTML-вміст всередині кореня React перед рендерингом React-компонента в ньому.

  • Якщо DOM-вузол вашого кореня містить HTML, згенерований React на сервері або під час збірки, використовуйте замість цього hydrateRoot(), який приєднує обробники подій до існуючого HTML.

  • Якщо ви викликаєте render в тому самому корені більше одного разу, React оновить DOM за необхідності, щоб відобразити останній переданий JSX. React вирішить, які частини DOM можна використовувати повторно, а які потрібно відтворити заново, "зіставивши їх" з раніше відрендереним деревом. Повторний виклик render у тому ж корені подібний до виклику функції set у кореневому компоненті: React уникає непотрібних оновлень DOM.


root.unmount()

Викличте root.unmount для знищення відрендереного дерева всередині кореня React.

root.unmount();

Застосунок, повністю побудований на React, зазвичай не має викликів до root.unmount.

Це здебільшого корисно, якщо вузол DOM вашого кореня React (або будь-який з його предків) може бути видалений з DOM іншим кодом. Наприклад, уявіть собі панель вкладок jQuery, яка видаляє неактивні вкладки з DOM. Якщо вкладка буде видалена, все, що знаходиться всередині неї (включаючи корені React всередині), також буде видалено з DOM. У такому випадку вам потрібно сказати React, щоб він "припинив" керувати вмістом видаленого кореня, викликавши root.unmount. Інакше компоненти всередині видаленого кореня не знатимуть, що потрібно очистити і звільнити глобальні ресурси, такі як підписки.

Виклик root.unmount демонтує всі компоненти в корені та "від'єднає" React від кореневого DOM-вузла, включно з видаленням будь-яких обробників подій або станів у дереві.

Параметри

root.unmount не приймає жодних параметрів.

Повернення

root.unmount повертає undefined.

Застереження

  • Виклик root.unmount демонтує всі компоненти у дереві та "від'єднає" React від кореневого DOM-вузла.

  • Після виклику root.unmount ви не можете викликати root.render з того самого кореня. Спроба викликати root.render у не змонтованому корені призведе до помилки "Неможливо оновити не змонтований корінь". Втім, ви можете створити новий корінь для того самого вузла DOM після того, як попередній корінь для цього вузла буде демонтовано.


Використання

Відображення застосунку, повністю зібраного з React

Якщо ваш застосунок повністю зібрано з React, створіть єдиний корінь для всього вашого застосунку.

"]]" class="language-js">import { createRoot } from 'react-dom/client';

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

Зазвичай, вам потрібно виконати цей код лише один раз під час запуску. Він виконає:

  1. Знайдіть вузол DOM браузера browser</CodeStep> визначений у вашому HTML.</li> <li>Відобразити <CodeStep data-step="2">React-компонент</CodeStep> для вашого застосунку всередині.</li></ol> </MaxWidth> <Пісочний пакет> <pre><code data-meta="index.html" class="language-html"><!DOCTYPE html> <html> <head><title>Мій застосунок</title></head> <body> <!-- Це вузол DOM --> <div id="root"></div> </body> </html>
    import { createRoot } from 'react-dom/client';
    import App from './App.js';
    import './styles.css';
    
    const root = createRoot(document.getElementById('root'));
    root.render(<App />);
    import { useState } from 'react';
    
    export default function App() {
      return (
        <>
          <h1>Hello, world!</h1>
          <Counter />
        </>
      );
    }
    
    function Counter() {
      const [count, setCount] = useState(0);
      return (
        <button onClick={() => setCount(count + 1)}>
          You clicked me {count} times
        </button>
      );
    }

    Якщо ваш застосунок повністю зібрано з React, вам не потрібно створювати більше коренів або викликати root.render знову.

    З цього моменту React буде керувати DOM всього вашого застосунку. Щоб додати більше компонентів, вкладіть їх у компонент App. Коли вам потрібно оновити інтерфейс, кожен з ваших компонентів може зробити це за допомогою стану використання. Якщо вам потрібно відобразити додатковий вміст, наприклад, модальне вікно або підказку поза вузлом DOM, відобразіть його за допомогою порталу.

    Коли ваш HTML порожній, користувач бачить порожню сторінку, доки не буде завантажено та запущено JavaScript-код програми:

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

    Це може здатися дуже повільним! Щоб вирішити цю проблему, ви можете згенерувати початковий HTML з ваших компонентів на сервері або під час збірки.Тоді ваші відвідувачі зможуть читати текст, бачити зображення і переходити за посиланнями ще до того, як завантажиться код JavaScript. Ми рекомендуємо використовувати фреймворк, який виконує цю оптимізацію одразу після установки. Залежно від того, коли він виконується, це називається рендерингом на стороні сервера (SSR) або статичною генерацією сайту (SSG).

    застосунки, що використовують серверний рендеринг або статичну генерацію, повинні викликати hydrateRoot замість createRoot. Після цього React буде гідратувати (повторно використовувати) DOM-вузли з вашого HTML, замість того, щоб знищувати та створювати їх заново.


    Відображення сторінки, частково зібраної за допомогою React

    Якщо ваша сторінка не повністю зібрана за допомогою React, ви можете викликати createRoot декілька разів, щоб створити корінь для кожного фрагменту UI верхнього рівня, керованого React. Ви можете відображати різний вміст у кожному корені, викликавши root.render.

    .

    Тут два різних React-компоненти рендеряться у два DOM-вузли, визначені у файлі index.html:

    <!DOCTYPE html>
    <html>
      <head><title>My app</title></head>
      <body>
        <nav id="navigation"></nav>
        <main>
          <p>This paragraph is not rendered by React (open index.html to verify).</p>
          <section id="comments"></section>
        </main>
      </body>
    </html>
    import './styles.css';
    import { createRoot } from 'react-dom/client';
    import { Comments, Navigation } from './Components.js';
    
    const navDomNode = document.getElementById('navigation');
    const navRoot = createRoot(navDomNode); 
    navRoot.render(<Navigation />);
    
    const commentDomNode = document.getElementById('comments');
    const commentRoot = createRoot(commentDomNode); 
    commentRoot.render(<Comments />);
    export function Navigation() {
      return (
        <ul>
          <NavLink href="/">Home</NavLink>
          <NavLink href="/about">About</NavLink>
        </ul>
      );
    }
    
    function NavLink({ href, children }) {
      return (
        <li>
          <a href={href}>{children}</a>
        </li>
      );
    }
    
    export function Comments() {
      return (
        <>
          <h2>Comments</h2>
          <Comment text="Hello!" author="Sophie" />
          <Comment text="How are you?" author="Sunil" />
        </>
      );
    }
    
    function Comment({ text, author }) {
      return (
        <p>{text} — <i>{author}</i></p>
      );
    }
    nav ul { padding: 0; margin: 0; }
    nav ul li { display: inline-block; margin-right: 20px; }

    Ви також можете створити новий вузол DOM за допомогою document.createElement() і додати його до документа вручну.

    const domNode = document.createElement('div');
    const root = createRoot(domNode); 
    root.render(<Comment />);
    document.body.appendChild(domNode); // You can add it anywhere in the document

    Щоб видалити React-дерево з DOM-вузла та очистити всі використані ним ресурси, викличте root.unmount.

    root.unmount();

    Це здебільшого корисно, якщо ваші React-компоненти знаходяться всередині програми, написаної в іншому фреймворку.


    Оновлення кореневого компонента

    Ви можете викликати render більше одного разу для одного кореня. Доки структура дерева компонентів збігається з тим, що було відрендерено раніше, React буде зберігати стан. Зверніть увагу, що ви можете вводити вхідні дані, а це означає, що оновлення від повторних викликів render щосекунди в цьому прикладі не є деструктивними:

    import { createRoot } from 'react-dom/client';
    import './styles.css';
    import App from './App.js';
    
    const root = createRoot(document.getElementById('root'));
    
    let i = 0;
    setInterval(() => {
      root.render(<App counter={i} />);
      i++;
    }, 1000);
    export default function App({counter}) {
      return (
        <>
          <h1>Hello, world! {counter}</h1>
          <input placeholder="Type something here" />
        </>
      );
    }

    Нерідко виклик render відбувається декілька разів. Зазвичай, ваші компоненти будуть оновлювати стан замість цього.


    Налагодження

    Я створив корінь, але нічого не відображається

    Переконайтеся, що ви не забули фактично зобразити вашу програму у корені:

    import { createRoot } from 'react-dom/client';
    import App from './App.js';
    
    const root = createRoot(document.getElementById('root'));
    root.render(<App />);

    Поки ви цього не зробите, нічого не буде відображено.


    Я отримую помилку: "Цільовий контейнер не є елементом DOM"

    Ця помилка означає, що те, що ви передаєте до createRoot не є вузлом DOM.

    Якщо ви не впевнені, що відбувається, спробуйте записати його у журнал:

    const domNode = document.getElementById('root');
    console.log(domNode); // ???
    const root = createRoot(domNode);
    root.render(<App />);

    Наприклад, якщо domNode дорівнює null, це означає, що getElementById повернув null. Це станеться, якщо на момент вашого виклику в документі не буде вузла з вказаним ідентифікатором. Причин для цього може бути декілька:

    >.
    1. Ідентифікатор, який ви шукаєте, може відрізнятися від ідентифікатора, який ви використовували в HTML-файлі. Перевірте, чи немає помилок!
    2. Тег вашого пакету <script>не може "бачити" вузли DOM, які з'являються післянього у HTML.

    Ще один поширений спосіб отримати цю помилку - написати createRoot(<App />) замість createRoot(domNode).


    Я отримую помилку: "Функції не є дійсними як дочірні React."

    Ця помилка означає, що те, що ви передаєте до root.render не є компонентом React.

    Це може статися, якщо викликати root.render з Component замість <Component />:

    // 🚩 Wrong: App is a function, not a Component.
    root.render(App);
    
    // ✅ Correct: <App /> is a component.
    root.render(<App />);

    Або якщо передати в root.render функцію, а не результат її виклику:

    // 🚩 Wrong: createApp is a function, not a component.
    root.render(createApp);
    
    // ✅ Correct: call createApp to return a component.
    root.render(createApp());

    Мій серверний HTML перестворюється з нуля

    Якщо ваш застосунок рендериться на сервері і містить початковий HTML, згенерований React, ви можете помітити, що створення кореня і виклик root.render видаляє весь цей HTML, а потім перестворює всі вузли DOM з нуля. Це може бути повільніше, призведе до скидання фокусу і позицій прокрутки, а також може призвести до втрати інших даних, введених користувачем.

    Програми, що рендеряться на сервері, повинні використовувати hydrateRoot замість createRoot:

    import { hydrateRoot } from 'react-dom/client';
    import App from './App.js';
    
    hydrateRoot(
      document.getElementById('root'),
      <App />
    );

    Зверніть увагу, що його API відрізняється. Зокрема, зазвичай не буде додаткового виклику root.render call.