如何将Next.js API生成的JSON数据传递到新路由并渲染至Flashcard组件
解决方案:在Next.js中将API数据传递到Flashcard组件
首先明确:useRouter是React客户端组件的Hook,不能在API路由(Node.js环境)里使用。API路由里要获取请求参数,直接用req.query(GET请求)或req.body(POST请求)即可。
下面给你两种常用的实现方式,根据你的场景选择:
方式一:客户端组件动态请求API(适合用户输入后实时获取数据)
在flashcard.js组件里,通过fetch调用你的API,拿到数据后存在组件状态里渲染卡片。
// components/flashcard.js 'use client'; // Next.js 13+ App Router需要加这个指令 import { useState } from 'react'; export default function Flashcard() { const [cards, setCards] = useState([]); const [subject, setSubject] = useState(''); const [topic, setTopic] = useState(''); // 触发获取练习题的函数 const loadCards = async () => { if (!subject || !topic) return; try { // 调用你的API,传递用户输入的参数 const res = await fetch(`/api/generate-cards?subject=${encodeURIComponent(subject)}&topic=${encodeURIComponent(topic)}`); if (!res.ok) throw new Error('获取数据失败'); const data = await res.json(); setCards(data); } catch (err) { console.error('请求错误:', err); } }; return ( <div> {/* 用户输入区域 */} <input type="text" value={subject} onChange={(e) => setSubject(e.target.value)} placeholder="输入不擅长的科目" /> <input type="text" value={topic} onChange={(e) => setTopic(e.target.value)} placeholder="输入主题" /> <button onClick={loadCards}>生成闪卡</button> {/* 闪卡渲染区域 */} <div className="flashcard-container"> {cards.map((card, index) => ( <div key={index} className="flashcard"> <div className="card-front">{card.question}</div> <div className="card-back">{card.answer}</div> </div> ))} </div> </div> ); }
方式二:页面组件服务端预获取数据(适合需要SEO或提前加载数据的场景)
如果flashcard.js是pages目录下的页面组件(或App Router里的页面),可以在服务端提前获取数据,再传递给组件渲染。
Pages Router 示例:
// pages/flashcard.js export default function FlashcardPage({ cards }) { return ( <div className="flashcard-container"> {cards.map((card, index) => ( <div key={index} className="flashcard"> <div className="card-front">{card.question}</div> <div className="card-back">{card.answer}</div> </div> ))} </div> ); } // 服务端获取数据 export async function getServerSideProps(context) { // 从URL参数里拿到用户输入的科目、主题 const { subject, topic } = context.query; // 调用API或直接复用生成练习题的逻辑(服务端内调用更高效) const res = await fetch(`http://localhost:3000/api/generate-cards?subject=${subject}&topic=${topic}`); const cards = await res.json(); return { props: { cards } // 传递给组件 }; }
App Router 示例(Next.js 13+):
// app/flashcard/page.js async function getCards(subject, topic) { const res = await fetch(`http://localhost:3000/api/generate-cards?subject=${subject}&topic=${topic}`, { cache: 'no-store' }); if (!res.ok) throw new Error('Failed to fetch data'); return res.json(); } export default async function FlashcardPage({ searchParams }) { const { subject, topic } = searchParams; const cards = await getCards(subject, topic); return ( <div className="flashcard-container"> {cards.map((card, index) => ( <div key={index} className="flashcard"> <div className="card-front">{card.question}</div> <div className="card-back">{card.answer}</div> </div> ))} </div> ); }
补充:API路由的正确写法
确保你的API路由在对应目录下,用req.query获取参数:
// pages/api/generate-cards.js export default async function handler(req, res) { // 获取请求参数 const { subject, topic } = req.query; // 你的练习题生成逻辑 const generatedCards = [ { question: `关于${subject}-${topic}的问题1`, answer: '答案1' }, { question: `关于${subject}-${topic}的问题2`, answer: '答案2' } ]; res.status(200).json(generatedCards); }
内容的提问来源于stack exchange,提问作者ThisIsRahmat
相关产品推荐
相关产品推荐

