在库中使用 React 路由器 - 无法使用 useHistory()
Posted
技术标签:
【中文标题】在库中使用 React 路由器 - 无法使用 useHistory()【英文标题】:React router use in library - not possible to use useHistory() 【发布时间】:2020-07-29 17:47:24 【问题描述】:我有一个包含多个应用程序和库的 monorepo,它运行得非常好(基于纱线)。我最近做了一些重构,并确定了一个我想在我的“公共”库中“外包”的公共组件。这包含一个使用ReactRouter.Route
的组件:
import React from 'react';
import Route, useHistory from 'react-router-dom';
export const AuthenticatedRoute = (props: Props): JSX.Element =>
const history = useHistory(); // Crashes here
... do auth stuff ...
useEffect(() =>
if (!authenticated)
history.push(...);
, []);
return (
<Route ...props>
props.children
</Route>
);
当包含我的 react 应用程序时,这个组件就像一个魅力。但是,当提取到commons
库中时,它在运行时会失败并出现以下错误:
Uncaught TypeError: Cannot read property 'history' of undefined
at useHistory (index.js:5914)
at AuthenticatedRoute (index.js:9848)
at renderWithHooks (react-dom.development.js:16260)
at mountIndeterminateComponent (react-dom.development.js:18794)
at beginWork$1 (react-dom.development.js:20162)
at htmlUnknownElement.callCallback (react-dom.development.js:336)
at Object.invokeGuardedCallbackDev (react-dom.development.js:385)
at invokeGuardedCallback (react-dom.development.js:440)
at beginWork$$1 (react-dom.development.js:25780)
at performUnitOfWork (react-dom.development.js:24695)
我猜这与库/应用程序如何引用 react-router-dom
库有关。
commons/package.json:
"name": "commons",
"version": "1.0.0",
"main": "dist/index.js",
"private": true,
"dependencies":
,
"peerDependencies":
"react-router-dom": "^5.1.2"
app/package.json:
"name": "app",
"version": "1.0.0",
"private": true,
"dependencies":
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2",
"commons": "1.0.0"
app/app.ts:
import React from 'react';
import BrowserRouter as Router from 'react-router-dom';
export const App = (): JSX.Element =>
return (
<Router>
<AuthenticatedRoute />
</Router>
);
;
注意:如果我评论 useHistory
,它会在 <Route>
上失败,说它需要是 <Router>
的子代。
我尝试过的事情:
使用peerDependencies
,以便库和应用使用相同的反应路由器实例
clean & yarn install 多次
react-router
和 react-router-dom
依赖项的任意组合
【问题讨论】:
您是否 100% 确定它被包裹在路由器中?像useParams
这样的其他钩子有用吗?
是的。当只将AuthenticatedRoute
(并更新c的导入)更改为app
模块时,它可以工作。其他钩子,例如 useEffect
工作正常,控制台中也没有警告。
@MikeKasperlik 你能找到解决这个问题的方法吗?我有同样的问题
我没有找到解决方案 - 我们最终将文件直接包含在应用程序中。
我在 monorepo 中遇到了这个问题,这篇文章为我提供了解决方案:***.com/questions/56750633/… 基本上将 react-router-dom 移动到库中的 peerDepencencies 并将其从汇总脚本中的构建中排除.
【参考方案1】:
withRouter
是一个 HOC。你必须相应地使用它。来自documentation:
import withRouter from "react-router";
class ShowTheLocation extends React.Component
static propTypes =
match: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
;
...
const ShowTheLocationWithRouter = withRouter(ShowTheLocation);
BrowserRouter
的初始化似乎没问题。
【讨论】:
不,那是旧的,并不能解决 op 遇到的问题 取决于版本。我想说的是useHistory
可能不存在,因此他无法从undefined
中读取某些内容。他可能会被一个过时的例子抓住。 > “6.0 中没有 useHistory 挂钩。切换回 5.1.2 或调整您的代码以不使用该挂钩”来自 github.com/ReactTraining/react-router/issues/7189。虽然乍一看范围似乎还可以。
是的,这是预挂钩。我也使用 5.1.2 - 查看最初的帖子依赖项。由于此组件在 1:1 复制到 app
时有效,因此它不能在代码本身中,但必须具有依赖关系。
您是否尝试过明确地创建历史记录并使用来自react-router
的Router
?以上是关于在库中使用 React 路由器 - 无法使用 useHistory()的主要内容,如果未能解决你的问题,请参考以下文章
AVFoundation PhotoApp - 在图像保存在库中之前无法使闪存正常工作