React+Next.js中Router.push失效:点击后无法加载更新数据
Next.js 点击跳转后数据不更新问题解决方案
问题根源
你使用了shallow: true进行路由跳转,这种模式下Next.js会跳过服务端数据获取(getServerSideProps/getStaticProps)和组件重新初始化流程,导致组件接收的post、blogs props始终是旧数据,只有刷新页面才会重新拉取最新数据。
解决方案
方案1:移除shallow: true选项
默认路由跳转(不设置shallow)会触发完整的页面更新逻辑,重新执行服务端数据获取函数并更新组件props,这是最直接的解决方式:
const getnewdata = (e, slugtype) => { e.preventDefault() routersss.push(slugtype) // 移除shallow配置,使用默认跳转行为 }
方案2:保留shallow路由,手动更新数据
如果必须使用shallow路由(比如需要无刷新跳转),可以通过监听路由参数变化,手动请求新数据并更新组件状态:
import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; const Post = ({ post: initialPost, blogs: initialBlogs }) => { const routersss = useRouter(); const [post, setPost] = useState(initialPost); const [blogs, setBlogs] = useState(initialBlogs); // 监听路由slug变化,拉取新数据 useEffect(() => { const fetchUpdatedData = async () => { // 根据当前路由slug请求对应文章数据 const postRes = await fetch(`/api/posts/${routersss.query.slug}`); const newPost = await postRes.json(); // 请求博客列表数据(如果需要更新) const blogsRes = await fetch('/api/blogs'); const newBlogs = await blogsRes.json(); setPost(newPost); setBlogs(newBlogs); }; fetchUpdatedData(); }, [routersss.query.slug]); // 仅当slug变化时执行 const getnewdata = (e, slugtype) => { e.preventDefault() routersss.push(slugtype, undefined, { shallow: true }) } return( <> <div className="img-content new-data" onClick={(e) => getnewdata(e, blog.slug)}> {/* 渲染更新后的post和blogs数据 */} </div> </> ) }
方案3:检查服务端数据获取逻辑
确保你的服务端数据获取函数(getServerSideProps/getStaticProps)正确依赖路由参数来获取对应数据:
// 页面组件外的服务端数据获取函数 export async function getServerSideProps(context) { // 从路由参数中获取slug const { slug } = context.params; // 根据slug请求对应文章数据 const postRes = await fetch(`https://your-api-domain/posts/${slug}`); const post = await postRes.json(); // 请求博客列表数据 const blogsRes = await fetch('https://your-api-domain/blogs'); const blogs = await blogsRes.json(); return { props: { post, blogs } // 将新数据传递给组件 }; }
额外注意
如果页面使用getStaticProps静态生成,需要配置getStaticPaths的fallback: true或fallback: 'blocking',确保动态路由的未预渲染页面能正常获取最新数据:
export async function getStaticPaths() { return { paths: [ // 预渲染的路径 { params: { slug: 'first-post' } } ], fallback: true // 未预渲染的路径会触发服务端渲染 }; }
内容的提问来源于stack exchange,提问作者prabhat mohal
相关产品推荐
相关产品推荐

