React Router v6同组件匹配不同URL不重新渲染如何解决?
问题根因
React Router v6中多个路由映射同一个组件时,React会复用现有组件实例,不会主动触发重渲染,只有当组件监听的路由相关依赖变化时才会更新逻辑。
方案1:监听路由参数更新(最推荐,无需强制重渲染)
直接在Posts组件内用useParams获取路由参数,将参数作为useEffect的依赖项,参数变化时重新拉取文章数据即可:
import { useParams, useEffect, useState } from 'react-router-dom' function Posts() { const { user_id } = useParams() const [posts, setPosts] = useState([]) useEffect(() => { // 文章列表请求逻辑 const loadPosts = async () => { let url = user_id ? `/api/posts?user_id=${user_id}` : '/api/posts' const res = await fetch(url) const data = await res.json() setPosts(data) } loadPosts() }, [user_id]) // 依赖项加入user_id,参数变化自动执行请求 // 剩余渲染逻辑 }
方案2:强制组件重新挂载
如果你的场景需要完全重置组件内部所有状态,必须让组件重新渲染,可以给Posts组件绑定和路由关联的动态key,key变化时React会自动销毁旧实例、挂载新实例:
首先修改路由配置,新增一个路由包装层获取参数:
// App.js import { Routes, Route, useParams } from 'react-router-dom' import { cloneElement } from 'react' import Posts from './Posts' // 路由包装组件,用于给子组件绑定动态key function RouteWithKey({ children }) { const { user_id } = useParams() // 根路由无user_id时用固定值,有参数时用user_id作为key return cloneElement(children, { key: user_id || 'all-posts' }) } function App() { return ( <Routes> <Route path='/' element={<RouteWithKey><Posts /></RouteWithKey>}/> <Route path='/user/:user_id/posts' element={<RouteWithKey><Posts /></RouteWithKey>}/> </Routes> ) }
之前加key不生效的原因
大概率是绑定的key为固定值,没有和路由参数/路径关联,key不变时React默认复用组件,不会触发重挂载。
内容的提问来源于stack exchange,提问作者ThriceGood
相关产品推荐
相关产品推荐

