无法读取未定义的属性“ history”(React Router 5的useHistory挂钩)


18

我正在使用几个星期前发布的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>
    )
}

Answers:


31

这是因为在该组件中未设置react-router上下文。由于它<Router>是设置上下文的组件,因此可以useHistory在子组件中使用,但不能在该子组件中使用。


谢谢布莱恩。这确实是问题的原因。:)
Radu Sturzu

1
Doh,当您指出时非常明显,谢谢
Jason Rogers

6

请注意其他遇到此问题并已经用Router组件包装了该组件的人。确保路由器和useHistory挂钩是从同一包中导入的。如果其中一个是从react-router导入的,而另一个是从react-router-dom导入的,而这些软件包的软件包版本不匹配,则可能引发相同的错误。不要同时使用它们,请在此处了解区别。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.