はじめに
Supabaseで
.select("*").eq("id", id)
を使ってデータを取得したとき、
1件だけのはずなのに配列([{}])で返ってきたことはありませんか?
実はこれはSupabaseの仕様で、
デフォルトでは常に配列として返すようになっています。
最初この点で自分も少しハマったため、
この記事では、その理由とシンプルな解決方法を紹介します。
問題の例
supabase
.from("study_spots")
.select("*")
.eq("id", id)
.then(({ data }) => console.log(data));
結果はこうなります
[ { id: 1, name: "カフェA" } ]
➡ 1件でも「配列」で返ってくる仕様になっている
このとき data の中身は「配列」なので、
data.name という書き方では値を取り出せません。
なぜなら、data という変数そのものは 配列(リストのようなもの) で、
その中の1番目(0番目の要素)にオブジェクトが入っているからです。
解決法(.single() を使う)
supabase
.from("study_spots") // テーブルを指定
.select("*") // 全カラム取得
.eq("id", id) // 条件一致(id)
.single() // 1件だけ返す
.then(({ data }) => setSpot(data)); // stateに保存
これで結果はこうなります
{ id: 1, name: "カフェA" }
data がオブジェクトになるので、
data.name や {spot.name} のように直接アクセスできます。
※SupabaseはSQLの結果を「行の配列」として返す仕様のため、
結果が1件でも [ { ... } ] のような形式になる。
.single() を付けることで、{ ... } の形に自動変換され、
React側でより扱いやすくなる。
まとめ
-
.select() は常に配列を返す仕様
-
.single() を付けると配列でなく1件のオブジェクトになる
-
Reactでは .then(({ data }) => setSpot(data)) でstateに保存して使う