React Router useParams返回空对象 点击跳转仅URL变化无页面更新
问题根因
你遇到的两个问题本质都是同一个原因:/和/folder/:folderId两个路由都渲染同一个Dashboard组件,React默认会复用同类型组件不会触发重渲染,导致:
useParams没有读取更新后的路由参数- 页面数据没有刷新
解决方案
方案1:给Dashboard组件加唯一key强制重渲染
修改App.js中的两个Dashboard路由,把component属性替换为render属性,给组件传入和路由绑定的唯一key,确保路由切换时组件重新初始化:
// 修改前 <PrivateRoute exact path='/' component={Dashboard} /> <PrivateRoute exact path='/folder/:folderId' component={Dashboard} /> // 修改后 <PrivateRoute exact path='/' render={props => <Dashboard key="root" {...props} />} /> <PrivateRoute exact path='/folder/:folderId' render={props => <Dashboard key={props.match.params.folderId} {...props} />} />
修改后useParams就能正常读取到folderId参数,组件也会重新执行所有hooks拉取对应文件夹的数据。
方案2:监听params变化更新数据(无需重渲染组件)
如果不想每次切换文件夹都重渲染整个Dashboard,可以保留现有路由配置,修改useDrive钩子:
- 在
useDrive内部读取useParams的folderId参数 - 把
folderId加入到拉取文件夹数据的useEffect依赖数组中,参数变化时自动重新拉取对应文件夹的内容:
// useDrive钩子示例修改 import { useParams } from 'react-router-dom' function useDrive() { const { folderId } = useParams() const [folder, setFolder] = useState(null) const [childFolders, setChildFolders] = useState([]) useEffect(() => { // 这里写根据folderId拉取对应文件夹和子文件夹数据的逻辑 const fetchFolderData = async () => { const data = await getFolderFromFirebase(folderId || 'root') // 根路径folderId为空时取根目录 setFolder(data.folder) setChildFolders(data.childFolders) } fetchFolderData() }, [folderId]) // 把folderId加入依赖,变化时重新执行 return { folder, childFolders } }
额外校验点
检查你自定义的PrivateRoute组件是否正确透传了路由属性,标准的v5版本PrivateRoute写法如下:
import { Route, Redirect } from 'react-router-dom' const PrivateRoute = ({ component: Component, ...rest }) => { const isAuthenticated = // 你的登录校验逻辑 return ( <Route {...rest} render={props => isAuthenticated ? <Component {...props} /> : <Redirect to="/login" /> } /> ) }
如果没有透传render回调的props给子组件,也可能导致路由相关的hooks读取异常。
内容的提问来源于stack exchange,提问作者KUSHAD
相关产品推荐
相关产品推荐

