如何在Next.js应用中执行指定的GraphQL查询?
你找的示例方向错了!
你看到的那个Next.js示例是用来在自己的项目里搭建GraphQL API服务的,需要写typeDefs和resolvers定义接口规则,但你的需求是调用外部第三方的GraphQL API(Rick and Morty的接口),完全不需要这套东西,直接像调用普通API一样发请求就行。
下面给你几种在Next.js里执行这个查询的正确方式:
方式1:客户端组件用原生fetch调用
如果是在客户端渲染的React组件里用,直接用fetch发POST请求:
async function fetchCharacters() { const res = await fetch('https://rickandmortyapi.com/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: ` query getCharacters { characters(page: 1) { info { count } results { id name } } } ` }) }); const data = await res.json(); return data.data.characters; } // 在组件里使用 export default function CharactersPage() { const [characters, setCharacters] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const loadData = async () => { const data = await fetchCharacters(); setCharacters(data); setLoading(false); }; loadData(); }, []); if (loading) return <div>加载中...</div>; return ( <div> <h1>总共有 {characters.info.count} 个角色</h1> <ul> {characters.results.map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> </div> ); }
方式2:服务端/静态生成时获取数据
如果需要在服务端提前获取数据(比如SEO友好的场景),可以用Next.js的getStaticProps或getServerSideProps:
用getStaticProps(静态生成,适合数据不常变的场景)
export async function getStaticProps() { const res = await fetch('https://rickandmortyapi.com/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: ` query getCharacters { characters(page: 1) { info { count } results { id name } } } ` }) }); const data = await res.json(); const characters = data.data.characters; return { props: { characters }, revalidate: 60 // 可选:每60秒重新生成页面 }; } export default function CharactersPage({ characters }) { return ( <div> <h1>总共有 {characters.info.count} 个角色</h1> <ul> {characters.results.map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> </div> ); }
用getServerSideProps(每次请求都在服务端获取数据)
export async function getServerSideProps() { const res = await fetch('https://rickandmortyapi.com/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: ` query getCharacters { characters(page: 1) { info { count } results { id name } } } ` }) }); const data = await res.json(); const characters = data.data.characters; return { props: { characters } }; } export default function CharactersPage({ characters }) { return ( <div> <h1>总共有 {characters.info.count} 个角色</h1> <ul> {characters.results.map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> </div> ); }
方式3:用SWR优化数据获取(推荐)
如果需要缓存、自动重新请求等功能,可以用Vercel官方的SWR库:
- 先安装依赖:
npm install swr
- 组件里使用:
import useSWR from 'swr'; const fetcher = async (query) => { const res = await fetch('https://rickandmortyapi.com/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query }) }); const data = await res.json(); return data.data.characters; }; export default function CharactersPage() { const query = ` query getCharacters { characters(page: 1) { info { count } results { id name } } } `; const { data: characters, error, isLoading } = useSWR(query, fetcher); if (error) return <div>加载失败</div>; if (isLoading) return <div>加载中...</div>; return ( <div> <h1>总共有 {characters.info.count} 个角色</h1> <ul> {characters.results.map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> </div> ); }
内容的提问来源于stack exchange,提问作者ChristianOConnor
相关产品推荐
相关产品推荐

