React 18でReactDOM.renderを使わなくてもコンポーネントをレンダリングする方法
React 18でReactDOM.renderが非推奨になった理由と対処方法
React 18では、クライアントレンダリングAPIが変更され、ReactDOM.render
は非推奨になりました。これは、React 18の新機能であるコンカレントモードとサーバーレンダリングの強化に対応するためです。
影響を受けるコード
ReactDOM.render
を使用してReactコンポーネントをDOMにレンダリングするコードはすべて、この変更の影響を受けます。
対処方法
ReactDOM.render
の代わりに、以下のいずれかの方法を使用する必要があります。
- ReactDOM.createRoot と root.render:
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
- react-dom/client:
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />);
以下のリソースを参照して、React 18でのクライアントレンダリングAPIの変更について詳しく学ぶことができます。
その他の注意事項
ReactDOM.render
はまだReact 18で動作しますが、将来のバージョンのReactで削除される予定です。react-dom/client
はReact 18で導入された新しいパッケージです。react-dom
パッケージを使用している場合は、react-dom/client
に移行することをお勧めします。
補足
- コンカレントモードは、React 18で導入された新機能です。コンカレントモードでは、ユーザー入力やネットワークリクエストなどの処理を妨げることなく、複数のコンポーネントを同時に更新することができます。
- サーバーレンダリングは、Reactアプリケーションをサーバー側でレンダリングする技術です。サーバーレンダリングを使用すると、ユーザーに最初のコンテンツをより迅速に提供することができます。
const App = () => {
return (
<div>
<h1>Hello, world!</h1>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
例2: react-dom/client
を使用したコード
import { createRoot } from 'react-dom/client';
const App = () => {
return (
<div>
<h1>Hello, world!</h1>
</div>
);
};
const root = createRoot(document.getElementById('root'));
root.render(<App />);
例3: コンカレントモードを使用するコード
const App = () => {
const [count, setCount] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setCount(prevCount => prevCount + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return (
<div>
<h1>Count: {count}</h1>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
例4: サーバーレンダリングを使用するコード
const App = () => {
return (
<div>
<h1>Hello, world!</h1>
</div>
);
};
const serverRenderer = require('react-dom/server');
const html = serverRenderer.renderToString(<App />);
res.send(html);
これらのサンプルコードは、React 18で ReactDOM.render
を使用せずにReactコンポーネントをレンダリングする方法を示しています。
React 18でReactDOM.renderを使用しないその他の方法
フックを使用する
React 18では、新しいフック useId
と useRef
を使用して、コンポーネントをDOMにレンダリングすることができます。
例:
const App = () => {
const [count, setCount] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setCount(prevCount => prevCount + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
const id = useId();
const ref = useRef();
useEffect(() => {
const element = document.getElementById(id);
ref.current = element;
element.addEventListener('click', () => {
setCount(prevCount => prevCount + 1);
});
return () => {
element.removeEventListener('click', () => {
setCount(prevCount => prevCount + 1);
});
};
}, [id]);
return (
<div>
<h1>Count: {count}</h1>
<div id={id} ref={ref}>
Click me!
</div>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
ポータルを使用する
const App = () => {
const [count, setCount] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setCount(prevCount => prevCount + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
const portal = ReactDOM.createPortal(<Count />);
return (
<div>
<h1>Count: {count}</h1>
{portal}
</div>
);
};
const Count = () => {
return (
<div>
<h1>Count: {count}</h1>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
サードパーティライブラリを使用する
react-dom
以外にも、Reactコンポーネントをレンダリングするために使用できるサードパーティライブラリがいくつかあります。
これらのライブラリは、react-dom
よりも軽量で高速な場合があります。
javascript reactjs