Closed4

SupabaseのDBからレコードを取得してアップデートするまでの流れ

hirotakahirotaka

前回GitHubで認証出来るようになり、ユーザーテーブルを作成しました。

https://zenn.dev/hrtk/scraps/8e2ec564334bfb

認証をすると、ユーザーテーブルにレコードが作成されるので、それを取得して、更新するまでをやってみます。

hirotakahirotaka

ログインして、セッションをセットしたら、セッションにユーザIDがあるので、それをキーにDBからユーザ情報を取得します。

pages/index.tsx
import { useEffect, useState } from 'react'
import { supabase } from '../lib/supabase-client'

export default function Home() {
  const [session, setSession] = useState()
  const [user, setUser] = useState(null)

  useEffect(() => {
    const { data: authListener } = supabase.auth.onAuthStateChange(
      (event, session) => {
        setSession(session)
      }
    )

    return () => {
      authListener.unsubscribe()
    }
  }, [])

  useEffect(() => {
    const setupUser = async () => {
      if (session?.user.id) {
        const { data: user } = await supabase
          .from('users')
          .select('*')
          .eq('id', session.user.id)
          .single()
        setUser(user)
      }
    }
    setupUser()
  }, [session])

  function signInWithGithub() {
    supabase.auth.signIn({ provider: 'github' })
  }

  function signOut() {
    supabase.auth.signOut()
  }

  return (
    <>
      {session ? (
        <div>
          <p>Hello, {user && user.full_name}</p>
          <button onClick={() => signOut()}>サインアウト</button>
        </div>
      ) : (
        <button onClick={() => signInWithGithub()}>GitHubでログイン</button>
      )}
    </>
  )
}
hirotakahirotaka

Updateはこんな感じになります。

pages/index.tsx
import { useEffect, useState, useRef } from 'react'
import { supabase } from '../lib/supabase-client'

export default function Home() {
  const [session, setSession] = useState()
  const [user, setUser] = useState(null)
  const [editingNickname, setEditingNickname] = useState(false)
  const newUsername = useRef()

  useEffect(() => {
    const { data: authListener } = supabase.auth.onAuthStateChange(
      (event, session) => {
        setSession(session)
      }
    )

    return () => {
      authListener.unsubscribe()
    }
  }, [])

  useEffect(() => {
    const setupUser = async () => {
      if (session?.user.id) {
        const { data: user } = await supabase
          .from('users')
          .select('*')
          .eq('id', session.user.id)
          .single()
        setUser(user)
      }
    }
    setupUser()
  }, [session])

  function signInWithGithub() {
    supabase.auth.signIn({ provider: 'github' })
  }

  function signOut() {
    supabase.auth.signOut()
  }

  async function setNickname(evt) {
    evt.preventDefault()

    try {
      const nickname = newUsername.current.value

      const { data: newUser } = await supabase
        .from('users')
        .update({ nickname })
        .match({ id: user.id })
        .single()

      setUser(newUser)
      setEditingNickname(false)
      newUsername.current.value = ''
    } catch (err) {
      console.log('Something went wrong')
    }
  }

  return (
    <>
      {session ? (
        <div>
          <p>Hi, {user?.nickname ? user.nickname : user?.full_name}</p>
          <div>
            {editingNickname ? (
              <form onSubmit={setNickname}>
                <input
                  type="text"
                  required
                  ref={newUsername}
                  placeholder="New username"
                />
                <button type="submit">設定</button>
              </form>
            ) : (
              <div>
                <button onClick={() => setEditingNickname(true)}>
                  ニックネームを更新
                </button>
              </div>
            )}
          </div>
          <button onClick={() => signOut()}>サインアウト</button>
        </div>
      ) : (
        <button onClick={() => signInWithGithub()}>GitHubでログイン</button>
      )}
    </>
  )
}
このスクラップは2021/10/01にクローズされました