Next.js中useEffect阻止跳转及登录失效问题求助
问题描述
卡片列表页点击卡片跳转至详情页(URL携带id,示例:http://localhost:3000/cards/card?id=6539ccd487fa315543646ce5),通过router.query获取id后在useEffect中调用接口渲染卡片,此功能正常。
但在详情页点击编辑按钮更新MongoDB数据后,调用router.push('/user/cardsDashboard')无法跳转至列表页,仍停留在当前页面,同时触发useEffect中fetchEventForEditting函数报错:TypeError: Cannot read properties of null (reading 'name'),且出现Next.js自动登出(卡片需登录查看)。尝试router.push和redirect方法均无效。
相关代码:
获取数据代码
const { id } = router.query useEffect(() => { const fetchEventForEditting = async () => { try { const res = await axios.post('/api/card', {id} ) setName(res.data.card.name) } catch (error) { console.log(error) // 点击编辑按钮后触发此错误 } } fetchEventForEditting() }, [id])
编辑事件代码
const editEvent = async () => { try { setLoad(true) const res = await axios.post('/api/cards/updateSingleEvent', data) console.log(res.data) setUpdatedImage('') router.push('/user/cardsDashboard') // 数据更新后应跳转至此页面 } catch (error) { console.log(error) } finally { setLoad(false) } }
问题原因
- 数据校验缺失:编辑操作后,
router.query.id可能出现空值或异常变化,触发useEffect重新执行,此时/api/card接口返回的res.data.card为null,读取name属性时抛出错误,阻塞了路由跳转逻辑。 - 接口权限异常:编辑或查询接口的身份验证逻辑存在问题,比如操作后清除了用户会话、token失效,导致接口请求失败并触发登出。
- 路由跳转时机不当:状态更新(如
setUpdatedImage(''))未完成时就执行router.push,或页面加载状态(load)未正确释放,导致跳转被中断。
解决办法
1. 增加数据校验与错误兜底
修改获取数据的逻辑,提前校验id和返回数据,捕获错误后直接跳转列表页:
const { id } = router.query const router = useRouter() useEffect(() => { const fetchEventForEditting = async () => { if (!id) { router.push('/user/cardsDashboard') return } try { const res = await axios.post('/api/card', {id} ) if (res.data?.card) { setName(res.data.card.name) } else { router.push('/user/cardsDashboard') } } catch (error) { console.log(error) router.push('/user/cardsDashboard') } } fetchEventForEditting() }, [id, router])
2. 排查接口权限逻辑
- 检查
/api/cards/updateSingleEvent和/api/card接口的身份验证代码,确保编辑操作不会清除用户会话或token。 - 确认axios请求是否携带了正确的身份凭证(如请求头的
Authorization字段),避免因权限不足导致接口返回错误。
3. 优化路由跳转时机
等待状态更新完成后再执行跳转,或强制确保跳转逻辑执行:
const editEvent = async () => { try { setLoad(true) const res = await axios.post('/api/cards/updateSingleEvent', data) console.log(res.data) setUpdatedImage('') // 等待状态更新完成 await new Promise(resolve => setTimeout(resolve, 0)) router.push('/user/cardsDashboard') } catch (error) { console.log(error) } finally { setLoad(false) } }
4. 检查列表页权限校验
确认/user/cardsDashboard页面的登录校验逻辑,避免因会话失效导致跳转后被重定向到登录页(表现为“登出”)。
内容的提问来源于stack exchange,提问作者janko hrasko
相关产品推荐
相关产品推荐

