use clientとは
クライアント側でJavaScriptを実行する必要があるかを示す目印のこと。
"use client"
import { useEffect, useState } from "react"
export default function SSR(){
const [state, setState] = useState(undefined);
useEffect(()=>{
setState('client loaded')
},[])
return (
<>
<div>SSR Page</div>
<div>{state}</div>
</>
)
}
こんな感じで、useState, useEffectなどのReactのフックを使用したいとき(クライアント側で実行しなければならないものがあるとき)、つまりJavaScriptのコードを実行したいときに、最初に書いておく。
別ファイルの読み込み
use clientのコンポーネントからまったく関係ない別のファイルを読み込んだ場合も、クライアント側で実行される。
"use client"
import { useEffect, useState } from "react"
import "./lib" //追記
export default function SSR(){
const [state, setState] = useState(undefined);
useEffect(()=>{
setState('client loaded')
},[])
return (
<>
<div>SSR Page</div>
<div>{state}</div>
</>
)
}
別ファイルを読み込んだ後の実行は、クライアント側かサーバー側かをNext.jsは判断ができないため、両方で実行はされる。
use serverとは
サーバー側でJavaScriptを実行する必要があるかを示す目印のこと。
何も書いていない時はuse serverと同じ意味になる。
明示的に書くことはあまりない。(一部例外有)
注意
Next.jsでプロジェクトを構築する際には、サーバー側で完結できるものはサーバー側で収めておくのが原則。
そのため、上記のようにすべてのページにuse clientをかけると、そこに書かれているすべてがブラウザ側でレンダリングされてしまう。
画面の初期表示に時間がかかってしまうため、このやり方は非推奨。
コンポーネントの切り分けをしよう
クライアント側で処理しないといけない部分は、別のコンポーネントを切り分けておく。
アップルーターを使用してプロジェクトを作るとき、フォルダー構造が以下のように設定。
親フォルダ―/
┣ components/
│ ┣ClientCom.js
┣layout.js
┣lib.js
┣page.js
各ファイルの中身を再構成する。
"use client"
import { useEffect, useState } from "react"
export default function SSR(){
const [state, setState] = useState(undefined);
useEffect(()=>{
setState('client loaded')
},[])
return (
<>
<div>{state}</div>
</>
)
}
import "./lib"
import ClientComp from './components/ClientComp'
export default function SSR(){
return (
<>
<div>SSR Page</div>
<ClientComp />
</>
)
}
※layout.jsとlib.jsはあまり関係ないのでここでは省略。
これで、page.jsでサーバー側で実行が必要な部分が切り出され、ClientComp.jsにクライアント側で実行が必要な部分が記載されたことになる。
なるべくコンポーネントは分けてつけると○。