React+MUI项目报错:Element type is invalid 问题求助
报错信息
Element type is invalid: expected a string (for built-in components)
or a class/function (for composite components) but got: object. You
likely forgot to export your component from the file it's defined in,
or you might have mixed up default and named imports.Check the render method of
App. Error: Element type is invalid:
expected a string (for built-in components) or a class/function (for
composite components) but got: object. You likely forgot to export
your component from the file it's defined in, or you might have mixed
up default and named imports.
提供的代码
App 组件
import React from 'react'; import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import Navbar from './components/Navbar'; import routes from './routes'; const App = () => { return ( <Router> <Navbar /> <div className="container mt-4"> <Routes> {routes.map((route, index) => ( <Route key={index} path={route.path} element={route.component} /> ))} </Routes> </div> </Router> ); }; export default App;
routes 配置
import Blog from "./pages/Blog"; import Home from "./pages/Home"; import Team from "./pages/Team"; const routes = [ { path: '/', component: Home, exact: true }, // Use the component class/function, not JSX element { path: '/blog', component: Blog }, { path: '/team', component: Team }, ]; export default routes;
Navbar 组件
import React, { useState } from "react"; import AppBar from "@mui/material/AppBar"; import Toolbar from "@mui/material/Toolbar"; import Button from "@mui/material/Button"; import { Link, useLocation } from "react-router-dom"; import HistoryDrawer from "./HistoryDrawer"; const Navbar = () => { const [openDrawer, setOpenDrawer] = useState(false); const location = useLocation(); const toggleDrawer = () => { setOpenDrawer(!openDrawer); }; return ( <React.Fragment> <AppBar position="static"> <Toolbar> <Button color="inherit" component={Link} to="/" selected={location.pathname === "/"} > Home </Button> <Button color="inherit" component={Link} to="/blog" selected={location.pathname === "/blog"} > Blog </Button> <Button color="inherit" component={Link} to="/team" selected={location.pathname === "/team"} > Team </Button> <Button edge="start" color="inherit" aria-label="menu" onClick={toggleDrawer} > History </Button> </Toolbar> </AppBar> <HistoryDrawer toggleDrawer={toggleDrawer} openDrawer={openDrawer}/> </React.Fragment> ); }; export default Navbar;
问题排查与解决
1. React Router v6 Route 组件用法错误
这是核心问题:React Router v6 要求Route的element属性传入JSX元素(即<Component />),而非组件引用(Component)。你当前直接传递route.component(如Home),不符合API规范,导致React无法识别类型抛出错误。
修改App组件的路由渲染逻辑:
{routes.map((route, index) => ( <Route key={index} path={route.path} element={<route.component />} /> ))}
同时,v6的Routes组件会自动匹配最精确路径,无需exact属性,可移除routes配置中的exact: true:
const routes = [ { path: '/', component: Home }, { path: '/blog', component: Blog }, { path: '/team', component: Team }, ];
2. 检查 HistoryDrawer 组件的导出/导入
报错提示存在导出/导入错误可能,需确认HistoryDrawer组件是否使用默认导出(对应Navbar中的import HistoryDrawer from "./HistoryDrawer";)。组件代码末尾需包含:
export default HistoryDrawer;
若使用命名导出,需将导入改为import { HistoryDrawer } from "./HistoryDrawer";,但保持默认导出更适配当前代码逻辑。
3. 修复Navbar中Button的无效属性
MUI的Button组件无selected属性,当前设置的selected={location.pathname === "/"}不会生效,还可能引发警告。可改用useMatch钩子判断路径,通过variant或自定义样式标记选中状态:
import { Link, useMatch } from "react-router-dom"; // Navbar组件内部 const homeMatch = useMatch('/'); const blogMatch = useMatch('/blog'); const teamMatch = useMatch('/team'); // 修改Button示例 <Button color="inherit" component={Link} to="/" variant={homeMatch ? "outlined" : "text"} > Home </Button>
内容的提问来源于stack exchange,提问作者Gr3ch4

