React路由组件警告:Functions are not valid as a React child 求助
解决React Router + Transition Group的"Functions are not valid as a React child"警告
问题背景
开发Navbar组件时,用react-router-dom实现页面路由,react-transition-group做页面过渡动画,出现以下警告:
Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it. at Routes (http://localhost:3000/static/js/bundle.js:41517:5) at Router (http://localhost:3000/static/js/bundle.js:41450:15) at BrowserRouter (http://localhost:3000/static/js/bundle.js:40259:5) at Navbar
附上相关代码:
import {React, Fragment } from 'react'; import { BrowserRouter, Routes, Route, Link, NavLink } from 'react-router-dom'; import { CSSTransition } from 'react-transition-group'; import Home from '../App'; import About from './About'; import Skills from './Skills'; import Proyects from './Proyect'; import Blog from './Blog' import Contact from './Contact' const routes=[ { path: "/", name: "Home", Component: Home }, { path: "/about", name: "About", Component: About }, { path: "/skills", name: "Skills", Component: Skills }, { path: "/proyects", name:"Proyects", Component: Proyects }, { path: "/blog", name:"Blog", Component: Blog}, { path: "/contact", name: "Contact", Component: Contact } ] function Navbar(props) { return ( <BrowserRouter> <ul className="ul-enlaces"> {routes.map((route, index) => ( <li key={index} className={route.name}> <Link key={route.path} as={NavLink} to={route.path}> {route.name} </Link> </li> ))} </ul> <Routes> {routes.map((route, index) => ( <Fragment key={index}> <Route key={index} exact path={route.path} element={route.Component} > {({match}) => ( <CSSTransition in={match != null} timeout={300} classNames="page" unmountOnExit > </CSSTransition> )} </Route> </Fragment> ))} </Routes> </BrowserRouter> ); } export default Navbar;
问题根源
- Route的element属性错误:直接传递了组件函数
route.Component,但element需要接收组件实例(即<route.Component />),这是触发警告的直接原因。 - React Router v6 API变更:v6版本的
Route不再支持通过children传递函数获取match对象,相关逻辑需改用useLocation钩子监听路由变化实现。 - CSSTransition使用不当:原代码中
CSSTransition未包裹实际页面组件,无法生效过渡效果。
修复方案
步骤1:修正Route的element属性
将element={route.Component}改为element={<route.Component />},传递组件实例而非组件函数。
步骤2:重构过渡动画实现
用react-router-dom的useLocation钩子监听路由变化,结合TransitionGroup和CSSTransition实现页面过渡;同时直接使用NavLink组件替代Link as={NavLink}的写法。
完整修复代码
import { React, useState, useEffect } from 'react'; import { BrowserRouter, Routes, Route, NavLink, useLocation } from 'react-router-dom'; import { CSSTransition, TransitionGroup } from 'react-transition-group'; import Home from '../App'; import About from './About'; import Skills from './Skills'; import Proyects from './Proyect'; import Blog from './Blog'; import Contact from './Contact'; const routes=[ { path: "/", name: "Home", Component: Home }, { path: "/about", name: "About", Component: About }, { path: "/skills", name: "Skills", Component: Skills }, { path: "/proyects", name:"Proyects", Component: Proyects }, { path: "/blog", name:"Blog", Component: Blog}, { path: "/contact", name: "Contact", Component: Contact } ]; // 封装路由过渡容器组件 const AnimatedRoutes = () => { const location = useLocation(); const [key, setKey] = useState(location.pathname); useEffect(() => { setKey(location.pathname); }, [location]); return ( <TransitionGroup> <CSSTransition key={key} timeout={300} classNames="page" unmountOnExit > <Routes location={location}> {routes.map((route, index) => ( <Route key={index} path={route.path} element={<route.Component />} /> ))} </Routes> </CSSTransition> </TransitionGroup> ); }; function Navbar(props) { return ( <BrowserRouter> <ul className="ul-enlaces"> {routes.map((route, index) => ( <li key={index} className={route.name}> <NavLink key={route.path} to={route.path} // 可选:给激活的导航项加样式 className={({ isActive }) => isActive ? 'active-link' : ''} > {route.name} </NavLink> </li> ))} </ul> <AnimatedRoutes /> </BrowserRouter> ); } export default Navbar;
补充说明
需要在CSS中定义过渡样式类才能看到动画效果,示例如下:
.page-enter { opacity: 0; transform: translateX(100%); } .page-enter-active { opacity: 1; transform: translateX(0); transition: opacity 300ms, transform 300ms; } .page-exit { opacity: 1; transform: translateX(0); } .page-exit-active { opacity: 0; transform: translateX(-100%); transition: opacity 300ms, transform 300ms; }
内容的提问来源于stack exchange,提问作者Mauro Arteaga
相关产品推荐
相关产品推荐

