React Router v6嵌套路由加载失败求助:Comments组件无法渲染
React Router v6 中 Comments 组件无法加载的解决办法
在 React Router v6 中,传递 quoteId 并尝试打开对应评论时,Comments 组件无法加载。尝试使用 loadable 组件解决无效,控制台无报错但出现以下警告:
You rendered descendant
(or called useRoutes()) at "/quotes/q1" (under) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
Please change the parentto .
问题代码
QuoteDetail 组件
import loadable from '@loadable/component'; // const Comments = loadable(() => import('../components/comments/Comments')); const QuoteDetail = () => { const params = useParams(); const quote = DUMMY_QUOTES.find(item => item.id === params.quoteId); const btnComment = <div className='centered'> <Link className='btn--flat' to={`/quotes/${params.quoteId}/comments`}>Load Comments</Link> </div> return ( <> <HighlightedQuote text={quote.text} author={quote.author} /> <Routes> <Route path={`/quotes/${params.quoteId}`} element={btnComment} /> <Route path={`/quotes/${params.quoteId}/comments`} element={<Comments />} /> </Routes> </> ) }
App 组件
import { Route, Routes } from "react-router-dom"; import AllQuotes from "./pages/AllQuotes"; import QuoteDetail from "./pages/QuoteDetail"; import NewQuote from "./pages/NewQuote"; import Layout from "./components/layout/Layout"; import NotFound from "./pages/NotFound"; const App = () => { return ( <Layout> <Routes> <Route path="/" element={<AllQuotes />} /> <Route path="/quotes" element={<AllQuotes />} /> <Route path="/quotes/:quoteId" element={<QuoteDetail />} /> <Route path="/new-quote" element={<NewQuote />} /> <Route path="*" element={<NotFound />} /> </Routes> </Layout> ); }
问题根源
警告已经明确说明:父路由 /quotes/:quoteId 未添加尾部的 *,导致导航到更深层级(如 /quotes/:quoteId/comments)时,父路由不再匹配,嵌套的子路由自然无法渲染。
修复步骤
修改 App 中的父路由配置
将 App 组件里的/quotes/:quoteId路由路径改为/quotes/:quoteId/*,允许匹配该路径下的所有子路由:import { Route, Routes } from "react-router-dom"; import AllQuotes from "./pages/AllQuotes"; import QuoteDetail from "./pages/QuoteDetail"; import NewQuote from "./pages/NewQuote"; import Layout from "./components/layout/Layout"; import NotFound from "./pages/NotFound"; const App = () => { return ( <Layout> <Routes> <Route path="/" element={<AllQuotes />} /> <Route path="/quotes" element={<AllQuotes />} /> {/* 添加尾部*,允许匹配子路由 */} <Route path="/quotes/:quoteId/*" element={<QuoteDetail />} /> <Route path="/new-quote" element={<NewQuote />} /> <Route path="*" element={<NotFound />} /> </Routes> </Layout> ); }简化 QuoteDetail 中的嵌套路由路径
父路由已包含/quotes/:quoteId,嵌套路由可使用相对路径,无需重复完整路径,既简洁又避免参数变化导致的路径错误:import loadable from '@loadable/component'; // 启用懒加载注释 const Comments = loadable(() => import('../components/comments/Comments')); const QuoteDetail = () => { const params = useParams(); const quote = DUMMY_QUOTES.find(item => item.id === params.quoteId); const btnComment = <div className='centered'> {/* 使用相对路径跳转 */} <Link className='btn--flat' to="comments">Load Comments</Link> </div> return ( <> <HighlightedQuote text={quote.text} author={quote.author} /> <Routes> {/* 空路径匹配父路由的根路径 */} <Route path="" element={btnComment} /> {/* 相对路径匹配comments子路由 */} <Route path="comments" element={<Comments />} /> </Routes> </> ) }
内容的提问来源于stack exchange,提问作者Mahdi Narimani
相关产品推荐
相关产品推荐

