😺

supabaseにreact-queryとnextjsで入門した話

2022/07/08に公開2

supabaseにreact-queryとnextjsで入門した話とか言ってますけどudemyでsupabase入門2回と自分で2回作ったからいけるやろっていうノリで書き記します。なおバックエンドの知識は0です

supabaseとは

  • Firebase の代替と言われている
  • 認証が楽
  • ポスグレっちゅーもんがベースらしい
  • やし高度なデータベス設計ができるらしい

知らんけど..!

Firebaseは2回ほどしか触っていないんですがUI的にsupabaseの方が好きです・・・

react-queryでしばきましょかー

react-queryの設定はここでは書きまへん

その前に.envの設定

NEXT_PUBLIC_SUPABASE_URL=自分の
NEXT_PUBLIC_SUPABASE_ANON_KEY=自分の

そしてトップディレクトリに utils/index.tsを作成する
てかフォルダ構造的に libでもええんですかねー?

utils/index.ts

import { createClient } from "@supabase/supabase-js";

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL as string,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY as string
);

データ取得

hooks/useQueryTasks.ts

import { useQuery } from "react-query";
import { supabase } from "../utils";
import { Task } from "../types";

export const useQueryTasks = () => {
  const getTasks = async () => {
    const { data, error } = await supabase
      .from("todos")
      .select("*")
      .order("created_at", { ascending: true });
    //
    if (error) throw new Error(error.message);
    //
    return data;
  };

  return useQuery<Task[], Error>({
    queryKey: "todos", // ユニークな名前
    queryFn: getTasks, // 定義した実行したい関数
    staleTime: Infinity, // キャッシデータの消費期限
  });
};

supabaseでのデータ取得はとーっても簡単😀
supabase.from("取得したいテーブル名").select("取得のしかた").***(ここは条件やら取得順やらを指定できる));

データ挿入

export const useMutateTask = () => {
  const queryClient = useQueryClient()
  const reset = useStore((state) => state.resetEditedTask)
  //
  const createTaskMutation = useMutation(
    // ここのasyncの引数taskは使用するコンポーネント先で使う時に
    //  createTaskMutation.mutate({ここに入るやつ!})
    async (task: Omit<Task, 'id' | 'created_at'>) => {
      const { data, error } = await supabase.from('todos').insert(task)
      if (error) throw new Error(error.message)
      return data
    },
    {
      onSuccess: (res) => {
        // react-queryのキャッシュからデータを取ってくる
        const previousTodos = queryClient.getQueryData<Task[]>('todos')
        if (previousTodos) {
          queryClient.setQueryData('todos', [...previousTodos, res[0]])
        }
        reset()
      },
      onError: (err: any) => {
        alert(err.message)
        reset()
      },
    }
  )

コメントがお恥ずかしい...
個人的メモですが消さないでおきます。
完全なるイメージですがasyncでデータを取ってきてonSuccessでキャッシュにアクセスしとるんですかね?
queryClient.getQueryData<Task[]>('todos')とはクライアント側のキャッシュデータを取得する型はTaskの配列でキャッシュのテーブル名はtodosやでと書いています

なんかふりがなjavascrptみたいな本を読んだのでご参考がてらに...
export先での使用方法は

const { createTaskMutation, updateTaskMutation } = useMutateTask()
const submitHandler = (e: FormEvent<HTMLFormElement>) => {
    // 押された時の始めの初期化
    e.preventDefault()
    createTaskMutation.mutate({
        title: editedTask.title,
        user_id: supabase.auth.user()?.id,
      })
}

createTaskMutation.mutate({
ここにuseStateで定義した状態などを入れて引数として
titleとuser_idを渡す
}}

zustandで書いたので正確にはuseStateではやっていないのですができると思います

データ更新とデータ削除

supabase.from('todos').update({ title: task.title }).eq(条件)
supabase.from('todos').delete().eq(条件)

こんな感じで簡単に書けます

表示の仕方

import { useQueryTasks } from '../hooks/useQueryTasks'
const { data: tasks, status } = useQueryTasks()
 if (status === 'loading') return <Spinner />
 if (status === 'error') return <p>{'Error'}</p>
 return (
   <ul className="my-2">
     {tasks?.map((task) => (
       <TaskItem key={task.id} id={task.id} title={task.title} />
     ))}
   </ul>
 )

react18で導入されたサスペンスを使うともっと綺麗に書けますよ ^ ^

アウトプットに技術記事書いてる人ほんまに尊敬します、、、
全然言語化できてないし伝わらんやろこんなメモ〜〜〜

疲れたので終わり

Discussion

najonajo

こんにちは!
もし可能であれば、タグの #supabseを #supabaseに修正いただけると助かります!

gensgens

めちゃくちゃ誤字ってますね。
変更しておきましたー!