NextJS v13.4中如何在页面加载时展示Route Handler返回的数据?
问题:页面加载时自动调用Route Handler并展示数据
我使用NextJS v13.4的新app router创建了一个Route Handler,通过GET请求从Supabase数据库获取全量数据,已能在客户端控制台看到返回的数据,但目前仅通过点击按钮触发请求。请问如何在页面加载时自动调用该Route Handler并展示数据?
现有代码
Route Handler(/app/api/tacos/route.js)
// /app/api/tacos/route.js import { NextRequest, NextResponse } from 'next/server'; import { supabaseClient } from '../../supabaseClient'; export async function GET() { try { const { data, error } = await supabaseClient.from('my_table').select('*'); // 原代码漏加await,此处修正 if (error) { return NextResponse.json({error: 'Error in getting the tacos from Supabase.'}, {status: 500}) } return NextResponse.json({data}, {status: 200}); } catch (error) { return NextResponse.json({message: 'Error in getting the tacos from the API.'}, {status: 500}); } }
注意:Supabase的查询是异步操作,必须添加
await才能拿到实际数据,原代码遗漏了这一步。
调用Route Handler的函数
const getAllTacos = async () => { const response = await fetch('/api/tacos', { method: 'GET' }); if(response.ok) { const { data } = await response.json(); console.log(data); return data; } else { throw new Error('Error on getAllTacos'); // 修正New为小写new } }
原按钮触发逻辑
return ( <div className="button bg-yellow-500" onClick={getAllTacos}>Get All Tacos</div> )
解决方案
方式一:客户端组件自动调用(useEffect)
如果你的页面是客户端组件(需添加'use client'指令),可以用useState存储数据,useEffect在组件挂载时自动发起请求:
'use client'; import { useState, useEffect } from 'react'; export default function TacosPage() { const [tacos, setTacos] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const getAllTacos = async () => { try { const response = await fetch('/api/tacos', { method: 'GET' }); if(response.ok) { const { data } = await response.json(); setTacos(data); } else { throw new Error('Failed to fetch tacos'); } } catch (err) { setError(err.message); } finally { setLoading(false); } }; // 组件挂载时自动执行请求 useEffect(() => { getAllTacos(); }, []); // 空依赖数组确保只执行一次 if (loading) return <div>加载中...</div>; if (error) return <div>出错了:{error}</div>; return ( <div> <h1>所有Tacos</h1> <ul> {tacos.map((taco, index) => ( <li key={index}>{taco.name}</li> {/* 根据你的数据实际字段调整 */} ))} </ul> {/* 保留按钮方便手动刷新 */} <div className="button bg-yellow-500" onClick={getAllTacos}>刷新Tacos</div> </div> ); }
方式二:服务端组件直接获取数据(更高效)
在NextJS 13.4的App Router中,服务端组件可以直接访问Supabase,无需通过Route Handler,减少一次网络请求,性能更优:
// /app/tacos/page.js(服务端组件,无需添加'use client') import { supabaseClient } from '../supabaseClient'; export default async function TacosPage() { try { const { data, error } = await supabaseClient.from('my_table').select('*'); if (error) throw new Error(error.message); return ( <div> <h1>所有Tacos</h1> <ul> {data.map((taco, index) => ( <li key={index}>{taco.name}</li> {/* 根据你的数据实际字段调整 */} ))} </ul> </div> ); } catch (err) { return <div>出错了:{err.message}</div>; } }
这种方式下,数据在服务端预渲染完成,页面加载时直接展示,无需客户端额外发起请求。
内容的提问来源于stack exchange,提问作者Octo Palm Tree
相关产品推荐
相关产品推荐

