我正在使用几个星期前发布的React Router的新useHistory挂钩。我的React-router版本是5.1.2。我的React版本为16.10.1。您可以在底部找到我的代码。
但是,当我从react-router导入新的useHistory时,出现此错误:
Uncaught TypeError: Cannot read property 'history' of undefined
这是由React-router中的这一行引起的
function useHistory() {
if (process.env.NODE_ENV !== "production") {
!(typeof useContext === "function") ? process.env.NODE_ENV !== "production" ? invariant(false, "You must use React >= 16.8 in order to use useHistory()") : invariant(false) : void 0;
}
return useContext(context).history; <---------------- ERROR IS ON THIS LINE !!!!!!!!!!!!!!!!!
}
由于它与useContext有关,并且可能与上下文冲突有问题,因此我尝试完全删除对useContext的所有调用,创建提供程序等。但是,此操作无济于事。试过React v16.8;一样。 我不知道是什么原因造成的,因为React路由器的所有其他功能都可以正常工作。
***请注意,调用其他React路由器钩子(例如useLocation或useParams)时,会发生相同的情况。
还有其他人遇到过吗?有什么想法可能导致这种情况吗? 任何帮助将不胜感激,因为我在网上找不到与此问题相关的任何信息。
import React, {useEffect, useContext} from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { Switch, useHistory } from 'react-router'
import { useTranslation } from 'react-i18next';
import lazyLoader from 'CommonApp/components/misc/lazyLoader';
import {AppContext} from 'CommonApp/context/context';
export default function App(props) {
const { i18n } = useTranslation();
const { language } = useContext(AppContext);
let history = useHistory();
useEffect(() => {
i18n.changeLanguage(language);
}, []);
return(
<Router>
<Route path="/">
<div className={testClass}>HEADER</div>
</Route>
</Router>
)
}
答案 0 :(得分:9)
这是因为未在该组件中设置react-router上下文。由于其<Router>
组件可以设置上下文,因此可以在子组件中使用useHistory
,但不能在该子组件中使用。
答案 1 :(得分:4)
useHistory 在您拥有路线的组件中不起作用,因为尚未设置 useHistory 所需的上下文。
useHistory 将对您在 Router 中声明的任何一个或多个子组件均有效,但不适用于 Router 的父组件或路由器组件本身。
答案 2 :(得分:2)
请注意其他遇到此问题并已经用Router组件包装了该组件的人。确保路由器和useHistory挂钩是从同一包中导入的。如果其中一个是从react-router导入的,而另一个是从react-router-dom导入的,而这些软件包的软件包版本不匹配,则可能引发相同的错误。不要同时使用它们,请阅读区别here。
答案 3 :(得分:2)
我将react-router-dom
从5.0.0更新为^ 5.1.2,此问题已解决。您可能会注意到useHistory
在子组件中。
答案 4 :(得分:0)
解决方案是:
在主要(父亲)组件中
import { BrowserRouter } from "react-router-dom";
<BrowserRouter><App /></BrowserRouter>
在子组件(应用程序)中
import { withRouter } from "react-router-dom";
function App(props) {
const { i18n } = useTranslation();
const { language } = useContext(AppContext);
let history = useHistory();
useEffect(() => {
i18n.changeLanguage(language);
}, []);
return(
<Route path="/">
<div className={testClass}>HEADER</div>
</Route>
)
}
export default withRouter(App);
答案 5 :(得分:0)
使用BrowserRouter。
import {
BrowserRouter as Router,
Route,
Switch,
} from 'react-router-dom';
如果使用路由器,则需要为其指定历史记录:
import {
Router,
Route,
Switch,
} from 'react-router-dom';
import createBrowserHistory from 'history';
const history = createBrowserHistory();
return (
<Router history={history} >
...
</Router>
);