无法读取未定义的属性 'history'(使用React Router 5的useHistory hook)。

46 浏览
0 Comments

无法读取未定义的属性 '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
            
        
    )
}

0
0 Comments

原因:

在拥有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 (
    

Home

); }; const About = () => { const history = useHistory(); // 可以正确使用useHistory return (

About

); }; export default App;

0
0 Comments

出现这个问题的原因是在使用`useHistory` hook时,`history`属性未定义。解决方法是确保`Router`组件和`useHistory` hook都是从相同的包中导入的。如果`Router`组件从`react-router`导入,而`useHistory` hook从`react-router-dom`导入,并且这两个包的版本不匹配,那么就会抛出相同的错误。要避免这种情况,需要使用相同的包。关于这两者之间的区别可以在这里阅读更多信息。

0
0 Comments

问题的原因是在该组件中未设置react-router的上下文。由于是<Router>组件设置了上下文,您可以在子组件中使用useHistory,但不能在该组件中使用。

解决此问题的基本策略如下:

const AppWrapper = () => {
  return (
    <Router> // 设置上下文
      <App /> // 现在App可以访问上下文
    </Router>
  )
}
const App = () => {
  let history = useHistory(); // 可用!
...
// 在此组件中渲染路由

然后,确保使用"wrapper"组件而不是直接使用App

谢谢Brian。确实是这个问题的原因。

他们应该只使用useStateuseContext,只复杂化了事情。

...解决方法可能是将Router提升。

在哪里使用AppWrapper

0