shinaps

github icongithub icon

Tech Blog

Next.jsのApp RouterでSupabaseのRealtimeを使用する

目次

Supabase Advent Calendar 2023の24日目の記事です。。現在12月25日ですが寝るまでは今日ということで、、、

この記事では、Next.jsのApp RouterでSupabaseのRealtimeを使用する方法について説明していきます。

なぜこれをやろうと思ったのかというと、最近、仕事でプランニングポーカーというのを行っているのですが、プランニングポーカーを行えるサービスで自分好みのものが見つからなかったので作ってみようと思ったからです。

SupabaseのRealtimeについてはチュートリアル程度しか触ったことがなかったのですが、今回アドベントカレンダーを書くために頑張ってみようと思いました。

まず、Realtimeを使用するテーブルで、Enable Realtimeにチェックを入れ、Realtimeを有効にします。

テーブルは以下のようになっており、ユーザーがルームに招待された時点でroom_userのレコードが作成され、画面上でカードを選択することで、valueが更新されるように処理を行います。

また、is_pendingは、「?」のカードを選択した時にtureに更新されるように処理を行います。

src/app/rooms/[slug]/page.tsxは以下のように設定しています。

export default async function Room({ params }: { params: { slug: string } }) {
  
	// 省略

  const { data: roomUsers } = await client
    .from('room_user')
    .select()
    .eq('room_id', room.id)

  return (
    <RoomComponent initialRoomUsers={roomUsers || []}/>
  )
}

そして、RoomComponentのリアルタイム更新部分は以下のようになっています。

export function RoomComponent({initialRoomUsers}: {initialRoomUsers: RoomUser[] | []}) {
  const [roomUsers, setRoomUsers] = useState<RoomUser[] | []>(initialRoomUsers)

  const updateRoomUser = (roomUser: RoomUser) => {
    setRoomUsers((prevRoomUsers) => {
      if (!prevRoomUsers) {
        return prevRoomUsers
      }

      return prevRoomUsers.map((prevRoomUser) => {
        if (prevRoomUser.user_id === roomUser.user_id) {
          return roomUser
        }

        return prevRoomUser
      })
    })
  }

  useEffect(() => {
    const channel = client
      .channel('room_user')
      .on(
        'postgres_changes',
        {
          event: 'UPDATE',
          schema: 'public',
          table: 'room_user',
          filter: `room_id=eq.${room.id}`,
        },
        (payload) => {
          updateRoomUser(payload.new as RoomUser)
        },
      )
      .subscribe()
    return () => {
      client.removeChannel(channel)
    }
  }, [])

  return // 省略
}

このように、サーバーコンポーネント側で初期値となるデータを取得し、それをクライアントコンポーネントに渡すことで、hookを使用せずに表現することができます。

Services

Contacts

© 2024 shinaps