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以前のコード
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での新しい書き方
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();
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();
さまざまなシナリオでの実装例
最小限の実装
import { createRoot } from 'react-dom/client';
import App from './App';
createRoot(document.getElementById('root')).render(<App />);
React Routerを使用する場合
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>
);
プログラムでルート要素を作成する場合
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')
の型アサーションが必要な場合があります:
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
トラブルシューティング
ルート要素が見つからない場合:
- HTMLに
<div id="root"></div>
が存在することを確認してください
- HTMLに
TypeScriptエラーが発生する場合:
- 適切な型アサーションを追加してください
HMR(Hot Module Replacement)の問題:
- React Refresh Webpack Pluginを使用していることを確認してください
参考情報
React 18の新機能や移行に関する詳細は、以下の公式リンクを参照してください:
React 18の新しいルートAPIへの移行は、将来の機能更新やパフォーマンス向上を確保するための重要なステップです。上記のガイドを参考にして、スムーズに移行を完了させましょう。