如何通过onClick修改getServerSideProps的Fetch URL并重新渲染新闻?
解决方案:通过URL查询参数触发getServerSideProps重新获取数据
你的思路存在核心问题:客户端修改的page变量仅存在于浏览器环境,服务端执行getServerSideProps时根本无法获取更新后的值,所以刷新页面后仍会使用服务端初始的page值。要实现点击按钮重新获取新数据,需用URL查询参数传递查询条件,让服务端感知变化并重新请求接口。
修改方案步骤:
- 将新闻查询的关键参数(关键词、日期、排序规则等)作为URL的查询参数(query params)
- 在
getServerSideProps中从请求上下文获取这些参数,动态构建请求URL - 客户端点击按钮时,通过修改URL的query参数触发页面重新渲染,进而让
getServerSideProps重新执行
修改后的完整代码:
import Head from "next/head"; import { NewsArticle, NewsResponse } from "@/modules/NewsArticles"; import { GetServerSideProps } from "next"; import NewsArticleGrid from "@/components/NewsArticleGrid"; import { Button } from "react-bootstrap"; import { useRouter } from "next/router"; interface BreakingNewsPageProps { newsArticles: NewsArticle[]; } export const getServerSideProps: GetServerSideProps<BreakingNewsPageProps> = async (context) => { // 从URL query获取参数,无参数时使用默认值(原Apple查询条件) const q = context.query.q || "apple"; const from = context.query.from || "2023-05-03"; const to = context.query.to || "2023-05-03"; const sortBy = context.query.sortBy || "popularity"; // 动态构建请求URL const apiUrl = `https://newsapi.org/v2/everything?q=${q}&from=${from}&to=${to}&sortBy=${sortBy}&apiKey=${process.env.NEWS_API_KEY}`; const response = await fetch(apiUrl); const newsResponse: NewsResponse = await response.json(); return { props: { newsArticles: newsResponse.articles }, }; }; export default function BreakingNewsPage({ newsArticles }: BreakingNewsPageProps) { const router = useRouter(); return ( <> <Head> <title>Breaking news </title> </Head> <main> <h1>Breaking News</h1> <Button onClick={() => { // 修改URL的query参数,触发getServerSideProps重新执行 router.push({ pathname: router.pathname, query: { q: "tesla", from: "2023-04-03", sortBy: "publishedAt" } }); }} > 切换到特斯拉新闻 </Button> <NewsArticleGrid articles={newsArticles} /> </main> </> ); }
方案可行性说明:
getServerSideProps每次请求都会执行,当URL的query参数变化时,它能从context.query拿到最新参数,动态构建新的API请求URL- 客户端通过
router.push修改query参数,会触发页面重新渲染,同时让服务端重新执行getServerSideProps获取新数据 - 这种方式还保留了URL的可分享性,用户复制链接后打开能直接看到对应的新闻内容
内容的提问来源于stack exchange,提问作者Александр
相关产品推荐
相关产品推荐

