这种情况主要发生在React-Router V6 的Route定义中,或者组件的加工与使用。
根据报错信息我们可以得知我们需要使用<Component/>的方式进行组件的使用,而不是Component,这样的话React会认为我们在调用函数,而不是使用组件。
如果你是在Router V6定义路由时发生的报错,应该参考以下代码:
代码语言:javascript复制<Route path="/" element={<Index/>} />
Copy
React TSX
而不是:
代码语言:javascript复制<Route path="/" element={Index} />//React会认为你传递了一个函数
Copy
React TSX
当然在其他时候使用也是一样的,如果参数需要你传递组件或者JSX,你大概率是直接传递了(Component)而不是<Component/>,将函数改为组件即可
如果你是在使用useRoutes进行路由懒加载时遇到这个报错,可以参考这两段代码:
类似Vue的路由懒加载,使用()=>import()引入然后map一下转为lazy(()=>import()),最后使用useRoute转为组件,在APP中使用
list.ts(路由列表)
代码语言:javascript复制import { lazy } from "react";
import type { FC,LazyExoticComponent } from "react";
const RouterList: RouterListType[] = [
{
path: "",
element: lazy(() => import("@/layout/Base")),
children: [
{
path: "/",
element: lazy(() => import("@/page/index")),
},
{
path: "/article/write",
element: lazy(() => import("@/page/article/write")),
},
{
path: "/article/list",
element:lazy(() => import("@/page/article/list")),
},
],
},
];
export default RouterList;
interface RouterListType {
path: string;
element: LazyExoticComponent<FC<{}>>;
children?: RouterListType[];
}
export type { RouterListType };
Copy
React TSX
switch.tsx(将list.ts中的内容嵌套Suspense)
代码语言:javascript复制import { lazy, Suspense, memo } from "react";
import { RouteObject, useRoutes } from "react-router";
import RouterList from "./list";
import type { RouterListType } from "./list";
const SetRouter = (list: RouterListType[]): RouteObject[] => {
let mRouteTable: RouteObject[] = [];
list.forEach(route => {
mRouteTable.push({
path: route.path,
element: (
<Suspense fallback={<div>路由加载ing...</div>}>
<route.element />
</Suspense>
),
children: route.children && SetRouter(route.children),
});
});
return mRouteTable;
};
export default memo(() => useRoutes(SetRouter(RouterList)));
Copy
React TSX
index.tsx(使用编译好的Router组件)
代码语言:javascript复制import { BrowserRouter } from "react-router-dom";
import Router from './Switch';
function RouterHub() {
return (
<BrowserRouter/>
<Router />
</BrowserRouter>
);
}
export default RouterHub;
Copy
TypeScript
然后直接放到<APP/>包裹就可以了