如何在React/Next.js中为全年日期生成API与对应页面?
实现动态日期路由并调用对应API
1. 创建嵌套动态路由结构
按照你需要的/today/feb/28格式,直接用嵌套动态路由即可,无需提前预设所有日期:
在项目目录中创建如下结构:
pages/ └── today/ └── [month]/ └── [day]/ └── index.js
这个结构会自动匹配所有/today/{月份缩写}/{日期}的请求,比如/today/feb/28、/today/jan/01等。
2. 处理月份缩写转数字
因为API需要两位数字的月份(比如02对应feb),可在组件内定义映射表完成转换:
const monthMap = { jan: '01', feb: '02', mar: '03', apr: '04', may: '05', jun: '06', jul: '07', aug: '08', sep: '09', oct: '10', nov: '11', dec: '12' };
3. 获取路由参数并调用API
根据使用的渲染方式,选择对应方法获取参数:
方式一:客户端渲染(CSR)
用useRouter钩子获取路由参数,再调用API:
import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; export default function DatePage() { const router = useRouter(); const { month, day } = router.query; const [data, setData] = useState(null); const [error, setError] = useState(null); useEffect(() => { if (!month || !day) return; // 转换月份为数字格式 const numericMonth = monthMap[month.toLowerCase()]; if (!numericMonth) { setError('无效的月份格式'); return; } // 调用API async function fetchData() { try { const res = await fetch(`https://api.mywebsite.org/data/all/${numericMonth}/${day}`); if (!res.ok) throw new Error('请求失败'); const result = await res.json(); setData(result); } catch (err) { setError(err.message); } } fetchData(); }, [month, day]); if (error) return <div>错误:{error}</div>; if (!data) return <div>加载中...</div>; return ( <div> <h1>{month.toUpperCase()} {day} 的信息</h1> {/* 渲染数据内容 */} <pre>{JSON.stringify(data, null, 2)}</pre> </div> ); }
方式二:服务端渲染(SSR)
用getServerSideProps在服务端获取数据,适合SEO友好场景:
const monthMap = { jan: '01', feb: '02', mar: '03', apr: '04', may: '05', jun: '06', jul: '07', aug: '08', sep: '09', oct: '10', nov: '11', dec: '12' }; export async function getServerSideProps(context) { const { month, day } = context.params; const numericMonth = monthMap[month.toLowerCase()]; // 校验月份有效性 if (!numericMonth) { return { notFound: true }; // 返回404页面 } // 校验日期合法性 const isValidDate = checkValidDate(numericMonth, day); if (!isValidDate) { return { notFound: true }; } try { const res = await fetch(`https://api.mywebsite.org/data/all/${numericMonth}/${day}`); if (!res.ok) throw new Error('API请求失败'); const data = await res.json(); return { props: { data, month, day } }; } catch (err) { return { notFound: true }; } } // 辅助函数:校验日期是否合法 function checkValidDate(month, day) { const date = new Date(2024, parseInt(month) - 1, parseInt(day)); return date.getMonth() + 1 === parseInt(month) && date.getDate() === parseInt(day); } export default function DatePage({ data, month, day }) { return ( <div> <h1>{month.toUpperCase()} {day} 的信息</h1> <pre>{JSON.stringify(data, null, 2)}</pre> </div> ); }
4. 可选:强化日期校验
上述SSR示例已包含日期合法性校验,你也可以在CSR中加入该逻辑,避免用户输入无效日期(如/today/feb/30)时发起无效API请求。
内容的提问来源于stack exchange,提问作者Kal
相关产品推荐
相关产品推荐

