You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;

问题根源

  1. Route的element属性错误:直接传递了组件函数route.Component,但element需要接收组件实例(即<route.Component />),这是触发警告的直接原因。
  2. React Router v6 API变更:v6版本的Route不再支持通过children传递函数获取match对象,相关逻辑需改用useLocation钩子监听路由变化实现。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 04:24:18