React Router Dom v6升级后jest测试报错 函数不能作为React子元素如何解决
问题解决方案
错误原因
- React Router v6 的
<Route>组件element属性要求传入已实例化的 React 节点(即<Component />格式),你修改后的代码直接传入了函数类型的ui(React.FC 本质是函数),没有实例化,因此触发「函数不能作为React子元素」的报错 - 额外隐患:你的自定义工具函数命名和@testing-library/react的render方法重名,会导致递归调用问题,需要先重命名导入的原生render方法
完整修正代码
// 首先把测试库的render重命名,避免递归调用 import { render as rtlRender, RenderResult } from '@testing-library/react'; import { createMemoryHistory } from 'history'; import { Router, Routes, Route } from 'react-router-dom'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; // 参数名ui改成大写Ui,避免JSX识别为原生HTML标签 const render = (Ui: React.FC, path: string, route: string): RenderResult => { const history = createMemoryHistory({ initialEntries: [route] }); const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, }, }, }); return { ...rtlRender( <QueryClientProvider client={queryClient}> <Router location={history.location} navigator={history}> <Routes> {/* 实例化组件后传入element属性 */} <Route path={path} element={<Ui />} /> </Routes> </Router> </QueryClientProvider>, ), }; };
兼容方案(无需修改参数名)
如果你不想调整原有参数命名,也可以用React.createElement方法创建节点,避免小写标签识别问题:
<Route path={path} element={React.createElement(ui)} />
额外注意事项
- 确保项目依赖的
history包版本为5.x,和React Router v6 的依赖要求匹配,避免出现路由相关的类型或运行时错误 - 如果你的组件需要接收自定义props,可以在实例化时传入,比如
<Ui {...customProps} />,可以按需扩展工具函数的参数支持
内容的提问来源于stack exchange,提问作者Jedi Schmedi
相关产品推荐
相关产品推荐

