我创建这篇文章是因为经过几个小时的搜索后,我在网上找不到解决方案,因此我将用解决方案回答我自己的问题,以防有人遇到与我相同的问题。
我有一个 React 应用程序,它使用
react-router-dom
进行路由和导航。我还有一个单独的自定义 NPM 包,其中包含在我的多个应用程序之间使用的共享逻辑。在此共享包中,我创建了一个自定义项,以便在 URL 搜索参数更改时执行一些状态更新:
// This custom hook is in my shared NPM package
import { useSearchParams } from 'react-router-dom';
export function useCustomHookExample(): void {
const [searchParams] = useSearchParams();
useEffect(() => {
// Do something with search params...
}, [searchParams]);
}
当我在自己的 React 应用程序中使用这个钩子时,我收到以下错误消息:
Uncaught Error: useLocation() may be used only in the context of a <Router> component.
显然,这是因为
useSearchParams
在内部使用了 useLocation
钩子,而这个钩子只能在 Router 上下文中调用。每次我试图在网上寻找遇到此问题的人时,人们似乎忘记了将路由器组件放置在树中更高的位置。但即使这样做之后我仍然遇到同样的问题:
export function AppRouter() {
return (
<BrowserRouter>
<Routes>
<Route path='/' element={<App />} />
</Routes>
</BrowserRouter>
);
}
export function App() {
// Still throws the error even though the hook was called within a Router context :(
useCustomHookExample();
...
}
所以在网上查找了几个小时后,我尝试查看
useLocation
钩子的源代码,我看到了以下评论:
// TODO: This error is probably because they somehow have 2 versions of the
// router loaded. We can help them understand how to avoid that.
`useLocation() may be used only in the context of a <Router> component.`
基本上,这告诉我,我的问题来自于我的应用程序中安装了两个版本的
react-router-dom
软件包:一个用于我的自定义 NPM 软件包,另一个用于我的 React 应用程序。为了解决这个问题,我只需将 react-router-dom
放入自定义包的对等依赖项中,以确保该包的唯一安装版本是我的应用程序使用的版本