16
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Next.js]ユーザーの動きにまつわるものはClientで

Posted at

はじめに

Next.jsのApp Routerにおいて、Server ComponentsとClient Componentsが現れました。正確にはReactの機能ですが。そしてv14でServer Actionsが現れました。これも正確にはReactの機能ですが。これはServerなの、Clientなのなど使い分けが一見混乱するかと思います。実際に自分が使ってみてこうしたほうがわかりやすいと思い4つに分類してみました。

GETはServer Componentsで

Server Componentsの中にClient Componentsが来ます。GETの通信処理はServer Componentsで行いましょう。すると表示も早く、またuseEffectで非同期処理や、SWRなどの非同期処理ライブラリなどを使わずasync awaitだけでGETできます。ここでGETしたものをClientに渡せば、Client側はGETに関する処理を持たなくて済むので動きだけに専念できます。
このとき、Client ComponentsはSuspenseで囲んであげましょう。

index.tsx
import { Suspense } from "react"
import { MyClient } form "./mycomponent"
import { Loading } from "./loading" //ローディング
export default async function Index() {
    const data = await fetch("https://api.example.com")
    return (
        <Suspense fallback={Loading}>
            <MyClient data={data} />
        </Suspsense>
    )
}

POSTなどの送信処理はServer Actionsで

POSTなどの送信処理はServer Actionsを通して行いましょう。ORMを使ってDBに直接POSTをしていなくても、REST APIなどでPOSTしている場合もServer Actionsを通して行うことをおすすめします。ユーザーが送るデータに関することをすべてNext.js側で責任がもてます。サーバー側のバリデーション処理だったり。
Server Actions自体はForm APIを通しているのでPOSTしかできませんが、その先にAPIを通していればPATCHやPUT、DELETEも送れると思います。
また送信するAPIのurlもユーザーからは見えなくなるため、そしてわざわざNext.js側でAPIディレクトリを作らず済むのでServer Actionsを使うことをお勧めします。

UXにまつわる全てのことはClient Componentで

動的に表示する、画面にエラーメッセージを出す、条件によってコンポーネントの出しわけをする、ページ遷移をする等々、ユーザーの動きに関することはすべてClient Componentで処理しましょう。
そもそもuseStateなどのReact Hooksを使う場合はServer Componentsで使えません。

例えば、Server Actionsで送信に成功したさいにページ遷移するにはどうしたらいいでしょうか?Server ActionsでNextResponseを使ってredirectでページ遷移することはおすすめしません。なぜならServer Actionsは今現在はそこまで便利なAPIを提供されているわけでもなくほぼ純粋なNode.jsみたいなものなので、Server Actions自身でURLを取得したりパスを取得したりするのも複雑になります。
Client Componentsに持たせればuseRouterなどのNext.jsのライブラリを利用できるので、パスの取得やページ遷移、ページ遷移する前になんらかのClient処理などが行えます。

ここで、formはClient Componentsにおくことをお勧めします。React Hook Formなどのフォームライブラリも使えますし、フォーム送信前後の処理も書くことができます。

form.tsx
'use client'

import { useRouter } from 'next/navigation'
import { useForm } from 'react-hook-form'
import { Action } from './action' //自作Server Action
import { useAlert } from './AlertHooks' //自作Alert

export default function Form() {
  const { trigger } = useForm()
  const { alert } = useAlert()
  const router = useRouter()
  return (
    <form
      action={async (data) => {
        //バリデーションの実行
        await trigger()
        await Action(data).then(() => {
          alert('成功しました')
          router.push('/dashboard')
        })
      }}
    >
      {/* ここにフォームの中身を書く */}
    </form>
  )
}

共通するサーバー処理はmiddlewareで

Next.jsにはmiddlewareというサーバー処理をするファイルがあります。例えば認証が必要なページでcookieがからだったらトップページにリダイレクトさせるなどの処理をするなど。ページ遷移はClientに持たせましょうといいましたが、認証処理などは逆にClient側でやるとuseEffectを駆使したり、一瞬ページが表示されてしまうなど工夫をしないとUXが悪くなるので、このようなリダイレクト処理はmiddlewareに持たせることをおすすめします。

終わりに

Next.jsの機能を大まかに4つにわけました。これによってApp routerの使い方に戸惑っている方も、うまく使い分けられるのではないでしょうか。
Server Components,Servr ActionsはGET POSTなどの通信処理に専念させると考えれば、Client Componentsが非常に書きやすくなると思います。

16
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?