React项目useContext路由跳转后404状态异常问题求助
React useContext 404状态残留问题解决方案
问题根源
useEffect依赖缺失:ProfileLocation组件的useEffect未将locId和fetchLocationById纳入依赖数组,导致URL参数变化(如从无效ID切换到有效ID)时,不会重新触发数据请求,直接读取之前残留的error404=true状态跳转404。- 全局状态未及时重置:访问无效ID后,Provider中的
error404状态保持为true,后续进入有效ID页面时,若未触发新的请求,状态不会自动重置;同时组件卸载时未清理相关状态,导致状态残留。
解决步骤
1. 修复useEffect依赖并稳定请求函数
在ProfileLocation组件中,补充useEffect的依赖数组,确保URL参数变化时重新请求数据:
useEffect(() => { fetchLocationById(locId) }, [locId, fetchLocationById]) // 添加locId和fetchLocationById作为依赖
同时在FetchDataProvider中用useCallback包裹fetchLocationById,避免函数每次渲染都重新创建导致useEffect频繁触发:
import React, { useState, createContext, useCallback } from "react" export const FetchDataProvider = ({ children }) => { // ... 原有状态定义 const fetchLocationById = useCallback(async (locId) => { try { setError404(false) setErrorAPI(false) // 同时重置API错误状态 const response = await fetchLocationData.getLocById(locId) response ? setLocationData(response) : setError404(true) } catch (err) { console.log(err) setErrorAPI(true) setError404(false) // 捕获错误时重置404状态 } finally { setIsLocationLoading(true) } }, []) // 若fetchLocationData.getLocById是稳定函数,依赖为空即可 // ... 原有fetchAllLocations函数及返回逻辑 }
2. 组件卸载时清理状态
在ProfileLocation中添加清理函数,离开详情页时重置相关状态,避免残留:
useEffect(() => { fetchLocationById(locId) // 组件卸载时重置状态 return () => { setError404(false) setErrorAPI(false) setIsLocationLoading(false) setLocationData({}) } }, [locId, fetchLocationById, setError404, setErrorAPI, setIsLocationLoading, setLocationData])
需要在FetchDataProvider的value中暴露状态更新函数:
return ( <FetchDataContext.Provider value={{ errorAPI, error404, isLocationLoading, allLocationLoading, locationData, locationsData, fetchLocationById, fetchAllLocations, // 新增:暴露状态更新函数 setError404, setErrorAPI, setIsLocationLoading, setLocationData, }} > {children} </FetchDataContext.Provider> )
3. 优化状态判断顺序
调整ProfileLocation中的判断逻辑,确保请求完成后再判断错误状态,避免异步请求未完成时误跳404:
if (!isLocationLoading) { return <Loader /> } if (errorAPI) { return ( <span> Oups une erreur est survenue ... Veuillez recommencer ultérieurement. </span> ) } if (error404) { return <Navigate to="/error404" /> } // 加载完成且无错误,渲染页面 return ( <> {/* 原有页面内容 */} </> )
4. 修正路由配置
明确/error404路由,避免path="*"覆盖正常404页面路径:
<Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/apartment/:locId" element={<ProfileLocation />} /> <Route path="/error404" element={<Error />} /> {/* 明确404页面路由 */} <Route path="*" element={<Navigate to="/error404" />} /> {/* 其他路径重定向到404 */} </Routes>
内容的提问来源于stack exchange,提问作者Thibaud-S
相关产品推荐
相关产品推荐

