使用Next.js 13和Supabase JS获取数据返回对象而非数组的问题
问题分析与解决方法
原因
- 你的
getData函数主动将数组包裹在了对象中返回,return { profiles }等价于return { profiles: profiles },所以拿到的结果自然是包含profiles数组的对象。 - 使用
useState/useEffect时,你直接把Supabase返回的profiles数组赋值给了状态,所以得到的是纯数组,没有额外包裹。 - 代码里
return { profiles };之后的if (!profiles)判断永远不会执行,属于不可达代码,逻辑完全无效。
解决方法
方法一:修改getData直接返回数组
调整函数返回值,去掉对象包裹,同时把判断逻辑移到return之前:
export const revalidate = 0; export default async function getData() { const { data: profiles } = await supabase .from("profiles") .select("*") .eq("is_host", true); // 先判断数据是否存在,再返回结果 if (!profiles || profiles.length === 0) { return []; } return profiles; // 直接返回数组,不再包裹对象 }
在组件中使用时,直接遍历返回的数组即可:
import getData from './path-to-getData'; export default async function HostsPage() { const profiles = await getData(); if (profiles.length === 0) { return <p>No hosts found</p>; } return ( <div> {profiles.map(host => ( <div key={host.id}>{host.full_name}</div> ))} </div> ); }
方法二:保留返回结构,在组件中正确解构
如果需要保持getData返回对象的结构,就在组件中解构出数组:
import getData from './path-to-getData'; export default async function HostsPage() { const { profiles } = await getData(); if (!profiles || profiles.length === 0) { return <p>No hosts found</p>; } return ( <div> {profiles.map(host => ( <div key={host.id}>{host.full_name}</div> ))} </div> ); }
同时修复getData中的不可达代码:
export const revalidate = 0; export default async function getData() { const { data: profiles } = await supabase .from("profiles") .select("*") .eq("is_host", true); if (!profiles || profiles.length === 0) { return { profiles: [] }; } return { profiles }; }
内容的提问来源于stack exchange,提问作者nelakay
相关产品推荐
相关产品推荐

