React Markdown博客上下篇按钮修复:从嵌套JSON获取文章URL
解决React Markdown博客上下篇文章切换问题
实现思路
- 扁平化嵌套的
city.json数据,将所有文章整理为一维数组便于查找 - 通过路由参数定位当前文章,计算前后篇文章的位置
- 使用React Router的路由跳转实现页面切换
- 根据前后篇是否存在控制按钮的禁用/置灰状态
完整Postpage.tsx代码示例
import { useParams, useNavigate } from 'react-router-dom'; import cityData from './city.json'; // 替换为你的json文件路径 const Postpage = () => { const { postID } = useParams<{ postID: string }>(); const navigate = useNavigate(); // 扁平化所有文章数据:将嵌套的PlaceList合并为一维数组 const allPosts = cityData.flatMap(state => state.PlaceList); // 找到当前文章在数组中的索引 const currentIndex = allPosts.findIndex(post => post.url === postID); // 获取前一篇/后一篇文章数据 const prevPost = currentIndex > 0 ? allPosts[currentIndex - 1] : null; const nextPost = currentIndex < allPosts.length - 1 ? allPosts[currentIndex + 1] : null; // 前一篇跳转逻辑 const handlePrevClick = () => { if (prevPost) navigate(`/blog/${prevPost.url}`); }; // 后一篇跳转逻辑 const handleNextClick = () => { if (nextPost) navigate(`/blog/${nextPost.url}`); }; return ( <div className="post-container"> {/* 文章内容渲染区域(保留你原有的Markdown渲染逻辑) */} <div className="post-content"> {/* ... 你的文章内容 ... */} </div> {/* 上下篇切换按钮组 */} <div className="post-nav"> <button onClick={handlePrevClick} disabled={!prevPost} className="nav-btn" > ← {prevPost ? `前一篇:${prevPost.title}` : '没有更多'} </button> <button onClick={handleNextClick} disabled={!nextPost} className="nav-btn" > {nextPost ? `后一篇:${nextPost.title}` : '没有更多'} → </button> </div> </div> ); }; export default Postpage;
样式补充(可选)
在CSS文件中添加按钮样式,优化置灰效果:
.post-nav { margin-top: 40px; display: flex; justify-content: space-between; } .nav-btn { padding: 10px 20px; border: none; border-radius: 4px; background-color: #2563eb; color: white; cursor: pointer; transition: opacity 0.2s; } .nav-btn:disabled { background-color: #94a3b8; cursor: not-allowed; opacity: 0.6; }
关键说明
- 数据扁平化:使用
flatMap将每个州的PlaceList数组展开,得到所有文章的一维数组,避免嵌套遍历的复杂度 - 索引定位:通过
findIndex匹配路由参数postID与文章的url字段,确定当前文章位置 - 路由跳转:使用
useNavigate钩子实现页面跳转,确保URL与路由配置一致 - 按钮状态:通过
disabled属性禁用无对应文章的按钮,配合CSS实现置灰效果;若需要隐藏按钮,可将disabled替换为style={{ display: prevPost ? 'block' : 'none' }}
内容的提问来源于stack exchange,提问作者aries0152
相关产品推荐
相关产品推荐

