我有一个包含 react-router-dom 的组件
Link
但是当我在 react-dom 中传递组件时抛出下面的错误renderToString
Uncaught Error: useHref() may be used only in the context of a <Router> component.
我不能将具有 React 钩子的组件传递到
renderToString
函数中吗?
import { renderToString } from 'react-dom/server';
const html = renderToString(<Contact />);
console.log(html);
我猜你在
useHref()
组件中使用了 <Contact/>
钩子。但
useHref()
钩子必须在 Router 上下文中使用,错误在 lib/hooks.tsx#L36 行抛出。来看看useHref()
钩子的源码:
export function useHref(to: To): string {
invariant(
useInRouterContext(),
// TODO: This error is probably because they somehow have 2 versions of the
// router loaded. We can help them understand how to avoid that.
`useHref() may be used only in the context of a <Router> component.`
);
let { basename, navigator } = React.useContext(NavigationContext);
let { hash, pathname, search } = useResolvedPath(to);
let joinedPathname = pathname;
if (basename !== "/") {
let toPathname = getToPathname(to);
let endsWithSlash = toPathname != null && toPathname.endsWith("/");
joinedPathname =
pathname === "/"
? basename + (endsWithSlash ? "/" : "")
: joinPaths([basename, pathname]);
}
return navigator.createHref({ pathname: joinedPathname, search, hash });
}
<StaticRouter>
做SSR,StaticRouter
组件使用底层的Router组件,Router
使用NavigationContext.Provider和LocationContext.Provider组件为其子组件提供上下文值, 然后你可以在这些子组件中使用 useHref()
钩子。
这是一个工作示例:
import React from 'react';
import { renderToString } from 'react-dom/server';
import { describe, it } from "@jest/globals";
import { Routes, Route, useHref } from 'react-router-dom';
import { StaticRouter } from 'react-router-dom/server';
const Contact = ({ to }) => {
const href = useHref(to)
return <pre>{href}</pre>
}
describe('76209110', () => {
it('should pass', () => {
const html = renderToString(
<StaticRouter location={'/courses'}>
<Routes>
<Route
path="courses"
element={<Contact to="advanced-react" />}
/>
</Routes>
</StaticRouter>
)
console.log('html: ', html)
})
})
测试结果:
console.log
html: <pre>/courses/advanced-react</pre>
at Object.<anonymous> (stackoverflow/76209110/index.test.tsx:24:13)
PASS stackoverflow/76209110/index.test.tsx
76209110
✓ should pass (66 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.42 s
包装版本:
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.8.1",