无JSX与工具链的React Router v6 SSCCE示例请求及报错排查
问题背景
我想在不使用JSX(且不涉及NPM工具链或Babel)的情况下使用React,需要一个符合SSCCE标准的React Router v6示例。
尝试代码及错误
尝试的JS代码:
ReactDOM.createRoot(document.querySelector('#root')).render( //React.createElement('p', null, 'A paragraph') React.createElement(ReactRouterDOM.Link, {to: 'somewhere'}, 'A link') );
对应的HTML:
<div id="root"></div> <script src="https://unpkg.com/react/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script> <script src="https://unpkg.com/react-router-dom/dist/umd/react-router-dom.development.js"></script>
运行后报错:
未捕获的类型错误:无法读取未定义属性(读取'useHref')
在LinkWithRef (index.tsx:416:16)
在renderWithHooks (react-dom.development.js:16315:20)
在updateForwardRef (react-dom.development.js:19236:22)
在beginWork (react-dom.development.js:21646:18)
在HTMLUnknownElement.callCallback (react-dom.development.js:4151:16)
在Object.invokeGuardedCallbackDev (react-dom.development.js:4200:18)
在invokeGuardedCallback (react-dom.development.js:4264:33)
在beginWork$1 (react-dom.development.js:27461:9)
在performUnitOfWork (react-dom.development.js:26570:14)
在workLoopSync (react-dom.development.js:26476:7)
错误原因
Link组件必须嵌套在React Router的路由上下文(如BrowserRouter)内部,否则无法获取路由相关的钩子函数(比如useHref),导致报错。
正确示例
以下是符合要求的完整SSCCE示例,纯用React.createElement实现,无需JSX、NPM或Babel:
<!DOCTYPE html> <html> <head> <title>React Router v6 无JSX示例</title> </head> <body> <div id="root"></div> <script src="https://unpkg.com/react/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script> <script src="https://unpkg.com/react-router-dom/dist/umd/react-router-dom.development.js"></script> <script> // 解构React Router DOM核心组件 const { BrowserRouter, Routes, Route, Link } = ReactRouterDOM; // 首页组件 function Home() { return React.createElement('div', null, React.createElement('h1', null, '首页'), React.createElement(Link, { to: '/about' }, '跳转到关于页') ); } // 关于页组件 function About() { return React.createElement('div', null, React.createElement('h1', null, '关于页'), React.createElement(Link, { to: '/' }, '返回首页') ); } // 渲染应用 ReactDOM.createRoot(document.getElementById('root')).render( // 用BrowserRouter包裹所有路由组件,提供路由上下文 React.createElement(BrowserRouter, null, // 导航栏 React.createElement('nav', null, React.createElement(Link, { to: '/' }, '首页'), React.createElement('span', { style: { margin: '0 10px' } }, '|'), React.createElement(Link, { to: '/about' }, '关于') ), // 路由配置 React.createElement(Routes, null, React.createElement(Route, { path: '/', element: React.createElement(Home) }), React.createElement(Route, { path: '/about', element: React.createElement(About) }) ) ) ); </script> </body> </html>
关键说明
- 所有路由相关组件(
Link、Routes、Route)必须放在BrowserRouter内部,确保能访问路由上下文。 Routes是v6的核心路由容器,内部用Route定义路径与组件的映射。Link用于实现单页应用的无刷新跳转,通过to属性指定目标路径。
内容的提问来源于stack exchange,提问作者Fernando Sanchez

