Movatterモバイル変換


[0]ホーム

URL:


Kazuhiro MimakiKazuhiro Mimaki
💨

React, Express でSSRを実現する

に公開

CSR(Client Side Rendering) と SSR (Server Side Rendering)

Create React App を使って作成されるアプリケーションは CSR(Client Side Rendering)で描画されます。CSR の場合、ブラウザは空の HTML をロードした後 JavaScript ファイルをロードしてコンポーネントを描画します。一方 SSR では、最初にサーバーサイド側で静的なページとして HTML を描画し、動的な JavaScript を後から注入します(hydration)。先に静的なページが表示されるため、初期描画の速度が上がります。

React における Server Side Rendering

ReactDOMServer.renderToString() というメソッドを利用することで、React Component をサーバー上で HTML として扱うことができ、hydrateRoot を利用することでその HTML に JavaScript をアタッチしてインタラクティブな動作を実現できます。

処理手順としは以下のようになります。

  1. サーバーサイドで構築された HTML を静的なページとしてブラウザに描画する。
  2. ブラウザは動的なページを構築するために必要な JavaScript をダウンロードする。
  3. コンポーネントの JavaScript がロードされた時点で、React は静的なページを動的なページに入れ替える。この時 1 で描画された DOM を再利用しつつ、イベントハンドラのみを設定する。
  4. イベントハンドラが設定され、最終的にユーザーはコンポーネントを操作できるようになる。

具体的な実装

具体的な実装を見ていきます。
リポジトリは以下にあります。

https://github.com/Kazuhiro-Mimaki/ssr-with-react-express

まずは最終的に描画したい簡単なコンポーネントを用意します。

src/App.jsx
importReact,{ useEffect, useState}from"react";exportconstApp=()=>{const[clientMessage, setClientMessage]=useState("");const[count, setCount]=useState(0);useEffect(()=>{setClientMessage("Hello World");},[]);return(<><h1>{clientMessage}</h1><h2>{count}</h2><buttononClick={()=>setCount((prev)=> prev+1)}>+Click</button></>);};exportdefaultApp;

次に、hydrate を行います。
React18 以降ではhydrateRoot を使えば、hydrate を行うことができます。
これにより、サーバーで描画されたただの HTML がインタラクティブなものになります。

src/index.jsx
importReactfrom"react";import{ hydrateRoot}from"react-dom/client";importAppfrom"./App";const container=document.getElementById("root");hydrateRoot(container,<App/>);

最後に、サーバーの処理です。
サーバーでは、初期に描画させたいコンポーネントを HTML として用意し、レスポンスします。

server/index.js
importexpressfrom"express";importReactfrom"react";importReactDOMServerfrom"react-dom/server";importAppfrom"../src/App";constPORT= process.env.PORT||4000;const app=express();app.get("/",(req, res)=>{// AppコンポーネントをHTML文字列に変換const app=ReactDOMServer.renderToString(<App/>);// HTMLに変換されたAppコンポーネントを埋め込んだHTMLを作成const html=`        <html lang="en">        <head>            <script src="client.js" async defer></script>        </head>        <body>            <div>${app}</div>        </body>        </html>`;// コンポーネントが埋め込まれたHTMLをレスポンス  res.send(html);});app.use(express.static("./build"));app.listen(PORT,()=>{console.log(`Server is listening on port${PORT}`);});

動作確認

npm run start

を実行して、http://localhost:4000 にアクセスします。
Hello World という文字列と count up できる数字が表示されていれば成功です。

参考

バッジを贈って著者を応援しよう

バッジを受け取った著者にはZennから現金やAmazonギフトカードが還元されます。


[8]ページ先頭

©2009-2025 Movatter.jp