🐕

【tRPC】NextJs & tRPC 【#10 tRPC Post get many query】

に公開

【#10 tRPC Post get many query】

YouTube: https://youtu.be/Vismdr7qfgw
https://youtu.be/Vismdr7qfgw

今回は作成した「post」のデータを取得して
表示する部分について実装を進めていきます。

src/app/page.tsx
import {
  SignInButton,
  SignUpButton,
  SignedIn,
  SignedOut,
  UserButton,
} from '@clerk/nextjs'

import { ClientGreeting } from '@/components/client-greeting'
import { CreatePostButton } from '@/components/create-post-button'
import { HydrateClient, trpc } from '@/trpc/server'
import { PostList } from '@/components/post-list'

export default async function Home() {
  void trpc.hello.prefetch({ text: 'tRPC' })
  void trpc.posts.getMany.prefetch()

  return (
    <HydrateClient>
      <ClientGreeting />
      <SignedOut>
        <SignInButton mode="modal" />
        <SignUpButton mode="modal" />
      </SignedOut>
      <SignedIn>
        <UserButton />
        <CreatePostButton />
      </SignedIn>
      <div>
        <PostList />
      </div>
    </HydrateClient>
  )
}
src/components/post-list.tsx
'use client'

import { Suspense } from 'react'
import { ErrorBoundary } from 'react-error-boundary'

import { trpc } from '@/trpc/client'

export const PostList = () => {
  return (
    <ErrorBoundary fallback={<div>Something went wrong</div>}>
      <Suspense fallback={<div>Loading...</div>}>
        <PostListTrpc />
      </Suspense>
    </ErrorBoundary>
  )
}

function PostListTrpc() {
  const [data] = trpc.posts.getMany.useSuspenseQuery()

  return (
    <ul>
      {data.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

ここまで出来ましたら、
「trpc.useUtils()」を使用して作成と同時に
新しく作成した「post」をブラウザに表示させます。

src/components/create-post-button.tsx
'use client'

import { Button } from '@/components/ui/button'
import { trpc } from '@/trpc/client'
import { toast } from 'sonner'

export const CreatePostButton = () => {
  const utils = trpc.useUtils()

  const createPost = trpc.posts.create.useMutation({
    onSuccess: () => {
      toast.success('Post created')
      utils.posts.getMany.invalidate()
    },
    onError: () => {
      toast.error('Something went wrong')
    },
  })

  return (
    <Button onClick={() => createPost.mutate({ title: 'Sample Title' })}>
      Post Create
    </Button>
  )
}

Discussion