无法读取未定义的属性 'history'(使用React Router 5的useHistory hook)。
无法读取未定义的属性 'history'(使用React Router 5的useHistory hook)。
我正在使用React Router的新useHistory hook,该hook在几周前发布。我的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有关,也许是与context的冲突有关,我尝试完全删除对useContext的所有调用,创建提供程序等等。但是,这没有任何作用。用React v16.8试过了,还是一样的问题。
我不知道是什么原因导致这个问题,因为React router的其他功能都正常工作。
***请注意,调用其他React router hooks(如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() } HEADER
原因:
在拥有Routes的组件中,useHistory无法工作,因为useHistory需要的上下文尚未设置。useHistory只能在Router的子组件中使用,而不能在Router的父组件或Router组件本身中使用。
解决方法:
将要使用useHistory的组件放在Router组件的子组件中,而非Router组件本身或Router的父组件中。这样就能够正确地使用useHistory。
代码示例:
import React from 'react'; import { BrowserRouter as Router, Route } from 'react-router-dom'; const App = () => { // 这里无法使用useHistory return ({/* 这里是Router的子组件,可以使用useHistory */} ); }; const Home = () => { const history = useHistory(); // 可以正确使用useHistory return ( ); }; const About = () => { const history = useHistory(); // 可以正确使用useHistory return (Home
); }; export default App;About
出现这个问题的原因是在使用`useHistory` hook时,`history`属性未定义。解决方法是确保`Router`组件和`useHistory` hook都是从相同的包中导入的。如果`Router`组件从`react-router`导入,而`useHistory` hook从`react-router-dom`导入,并且这两个包的版本不匹配,那么就会抛出相同的错误。要避免这种情况,需要使用相同的包。关于这两者之间的区别可以在这里阅读更多信息。
问题的原因是在该组件中未设置react-router
的上下文。由于是<Router>
组件设置了上下文,您可以在子组件中使用useHistory
,但不能在该组件中使用。
解决此问题的基本策略如下:
const AppWrapper = () => { return ( <Router> // 设置上下文 <App /> // 现在App可以访问上下文 </Router> ) } const App = () => { let history = useHistory(); // 可用! ... // 在此组件中渲染路由
然后,确保使用"wrapper"组件而不是直接使用App
。
谢谢Brian。确实是这个问题的原因。
他们应该只使用useState
和useContext
,只复杂化了事情。
...解决方法可能是将Router提升。
在哪里使用AppWrapper
?