Skip to content

React 18でのReactDOM.renderの廃止とcreateRootへの移行

React 18で導入された新しい変更により、ReactDOM.renderメソッドが非推奨となりました。この記事では、この変更の背景と適切な対応方法について詳しく解説します。

問題の概要

React 18以降、新しく作成したReactアプリケーションで以下の警告が表示されます:

WARNING

Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot

この警告は、Create React Appでアプリケーションを作成した際のデフォルトの設定がReact 18用に更新されていない場合に発生します。

なぜReactDOM.renderは非推奨になったのか

React 18では、新しいコンカレントレンダリング機能を導入するために、ルートAPIの大幅な変更が行われました。主な理由は以下の通りです:

  • パフォーマンスの向上と新しい機能のサポート
  • より効率的なレンダリングプロセスの実現
  • 非同期レンダリング機能の基盤の提供

従来のReactDOM.renderは下位互換性のために一時的にサポートされていますが、将来的に完全に削除される可能性があります。

基本的な解決方法

React 17以前のコード

javascript
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

reportWebVitals();

React 18での新しい書き方

javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from 'App';
import reportWebVitals from './reportWebVitals';

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

reportWebVitals();
typescript
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

reportWebVitals();

さまざまなシナリオでの実装例

最小限の実装

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

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

React Routerを使用する場合

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

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

プログラムでルート要素を作成する場合

javascript
import React, { useEffect } from 'react';
import { createRoot } from 'react-dom/client';

const App = () => {
  useEffect(() => {
    // コンポーネントのロジック
  }, []);

  return (
    <div>
      <h1>My Application</h1>
    </div>
  );
};

const rootEl = document.createElement('div');
document.body.appendChild(rootEl);
const root = createRoot(rootEl);
root.render(<App />);

変更点の詳細比較

項目React 17以前React 18
インポート方法import ReactDOM from 'react-dom'import ReactDOM from 'react-dom/client'
ルートの作成ReactDOM.render(element, container)ReactDOM.createRoot(container).render(element)
厳格モードオプション推奨(パフォーマンス向上)
ハイドレーションReactDOM.hydrate()ReactDOM.hydrateRoot()

注意点とベストプラクティス

TIP

  • 新しいAPIへの移行は必須ではありませんが、React 18の新機能を活用するために推奨されます
  • 既存のプロジェクトを移行する場合は、十分なテストを実施してください
  • Create React Appの最新版を使用すると、自動的に正しい設定が適用されます

WARNING

TypeScriptを使用している場合、document.getElementById('root')の型アサーションが必要な場合があります:

typescript
const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);

トラブルシューティング

  1. ルート要素が見つからない場合

    • HTMLに<div id="root"></div>が存在することを確認してください
  2. TypeScriptエラーが発生する場合

    • 適切な型アサーションを追加してください
  3. HMR(Hot Module Replacement)の問題

    • React Refresh Webpack Pluginを使用していることを確認してください

参考情報

React 18の新機能や移行に関する詳細は、以下の公式リンクを参照してください:


React 18の新しいルートAPIへの移行は、将来の機能更新やパフォーマンス向上を確保するための重要なステップです。上記のガイドを参考にして、スムーズに移行を完了させましょう。