1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Next.js14 AppRouter】無駄遣い削減アプリ「ちりつも」をリプレイス

Last updated at Posted at 2024-12-29

こんにちは。Naotoです。

今回は、以前T3 Stackで個人開発した無駄遣い削減アプリ「ちりつも」をリプレイスしたことについて記事にしました。

以前T3 Stackで開発した際の記事は以下です。
(アプリの機能や開発したきっかけなどは、以下記事をご覧ください。)

リプレイスした理由

今回リプレイスをした理由はNext.js14(AppRouter)に対する理解が、自分の中で曖昧であると感じたためです。

プログラミングを学ぶ上では、
"インプットよりアウトプットに時間をかけるべき"
とよく言われますが、逆に、自分はその言葉に甘えてしまい、アウトプットの方が楽しいが故に、インプットを疎かにしていました。

T3 Stackで開発した際も、そもそも AppRouterで何ができるようになったのか、どういった考え方・メンタルモデルのフレームワークなのか、などを理解しないまま、「動けば良い」という付け焼き刃的な技術で、開発を進めてしまいました。

そのため、「分かっているようで本当は分かっていない」というモヤモヤが自分の中にありました。

そこで、今回、AppRouterについて基礎から学習をし直した上で、基本に徹した方法で再度「ちりつも」を開発し直そうと思い、リプレイスに踏み切りました。

開発環境と使用技術

開発環境

OS:macOS
IDE:Visual Studio Code

使用技術

フレームワーク:Next.js v.14 AppRouter (React v.18)
言語:TypeScript
スタイル:Tailwind CSS, React Icons
認証:Next.Auth
ORM:Prisma
DB:PostgreSQL(Supabase)
パッケージ管理:npm
ソースコード管理:GitHub
テスト:Vitest, React Testing Library, Playwright
その他:zod, canvas-confetti, use-action-state-compat

※T3 Stackで開発した際に使用していたtRPCは使用しなくなりました。

T3 Stackを辞めた理由

クライアントとサーバー間のやり取りをServerActionsにしたかったから

T3 Stackとは、Next.js, TailwindCSS, TypeScript, Prisma, tRPC, Next.Authを使用した開発手法のことを言い、クライアントとサーバー間のやり取りは、tRPCを用いて行われます。

また、tRPCとは、フロント・バックエンドともにTypeScriptで開発している場合にのみ使用でき、バックエンドの処理をフロントエンドから関数のように(+型安全に)呼び出すことを可能にする技術です。

しかし、ServerActionsが登場したことで、tRPCと同様なことをより簡単に実現できると感じ、現時点でtRPCを使うメリットはあまりないと感じました。
(tRPCは設定がめんどくさいがServerActionsは設定がいらない。)

さらに、サードパーティライブラリを扱う前に、まずはNext.jsそのものについて理解する必要があると思った+公式としてもServerActionsの使用を推奨しているという点も踏まえ、今回は基礎に則り、tRPC(T3 Stack)ではなくServerActonsを使用することとしました。

Next.js14(App Router)の学習方法

基礎を学習する上で以下の教材・動画を使用しました。

Next.jsの公式ドキュメント

Next.jsの公式ドキュメントです。
「Learn Next.js」という学習用コンテンツがあり、基本的な実装方法を1通り学習することができます。

その他、通常のドキュメントも充実しています。

Zenn本 「Next.jsの考え方」

akfm_satoさんという方が書かれたZenn本です。
AppRouterについて、初心者〜中級者向けに、体系的にまとめられており、非常に勉強になりました。

ShinCodeさんの動画

Next.js AppRouterのベストプラクティスについてまとめられた動画です。
上記公式ドキュメントやakfm_satoさんの「Next.jsの考え方」をもとに作成されており、重要な部分がまとまっています。

リプレイスにあたって意識した点

上記にも記載しましたが、"AppRouterの基礎に則った開発をする"という点を一番意識ました。

その中でも特に意識した点を3つ紹介します。

可能な限りServerComponentsを使用すること

できる限りClientComponentsを使用しないようにしました。
例えば、以下のような画面では、フォームの部分(input×2とbutton部分)のみを切り離し、ClientComponentsとして実装するようにしました。

また、AppRouterでは、ClientComponents配下のComponentは全てClientComponentsになってしまうため、できるだけ末端のComponentsをClientComponentsにするよう意識しました。
(Compositionパターンを使用するという方法でも良いかと思います。)

image.png

4つキャッシュを理解した上で実装すること

AppRouterには以下4つのキャッシュが存在します。

  • RequestMemoization
  • DataCache
  • FullRouteCache
  • RouterCache

これらのキャッシュはパフォーマンスや画面更新等に大きく関わってくるため、しっかり理解する必要があります。

私的にはAppRouterを学ぶ中でキャッシュについての理解が一番難しく感じたため、Qiitaの記事にまとめながら理解を深めました。
個々のキャッシュの説明は以下記事をご覧ください。

キャッシュについて最も意識したことは、RequestMemoizationを利用したデータフェッチのコロケーションです。

データフェッチをできるだけそのデータを使用するComponents内で行うことで、Componentの独立性を高めつつ(propsバケツリレー防止)、その一方でリクエストが重複してしまう部分はRequestMemoizationで回避する、という方法をとりました。
そうすることで、Componentsの独立性とパフォーマンスの両方を保てるようにしました。

例)以下の場合、page.tsxでなく、List.tsxでデータ取得
image.png

また、今回は、API Handlerは使わず、ServerActions内で直接Prisma関数を呼び出したため、ReactCacheを用いてRequestMemoizationを使用しました。
(通常fetch()を用いたデータ取得でしかRequestMemoizationは機能しないため。)

// app/lib/commonFunction.ts(RequestMemoizationを機能させるためにデータ取得層にて共通化)
// 欲しいものリストの取得(ReactCahceを使用)
export const getWantedItemList = cache(async (userId: string) => {
  return prisma.wantedItem.findMany({
    where: { userId },
    orderBy: { createdAt: "desc" },
  });
});
v

※キャッシュの話とはズレますが、データフェッチはできる限り並行で行う(PromiseAll()の使用 or コンポーネントの兄弟分割)ことも意識しました。

Streamingの使用

「ちりつも」はユーザによる操作(データ更新など)が多いアプリのため、Static RenderingよりもDynamic Renderingのページが多くなってしまいました。

そのためデータ取得時には必ずStreamingを使用しました。

image.png

<div>
  <h2 className="mb-4 pl-1 text-xl font-bold text-gray-100 sm:text-2xl">
    欲しい物リスト
  </h2>
  <Suspense fallback={<SkeletonList />}>
    <List />
  </Suspense>
</div>

上記のようにSuspenseのfallbackにスケルトンUIを指定し、対応しました。

まとめ

上記の通り、Next.js14(AppRouter)について学習し直した上で、リプレイスを行いました。

インプット学習から逃げずに、AppRouterについて1から学んだことで、今まで理解が不十分でモヤモヤしていた部分がスッキリし、全体像をはっきりさせることができました。

今後は、アクセシビリティ対応やテスト、CI/CDなども勉強し、取り入れていきたいと考えております。

最後までお読みいただき、ありがとうございました。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?