开发者问题收集

React-router-dom 在读取 pathname 属性时抛出两个错误

2021-11-07
3227

当我使用带有 react-router-dom 6 的路由时,我看到两个不同的错误:

  1. TypeError:无法解构“undefinded”或“null”的属性“pathname”

  2. TypeError:无法读取未定义的属性(读取“pathname”) 并向我显示来自 react-router 文件的以下代码:C:/Users/FAMILIA/Desktop/packages/react-router/index.tsx:281

     let {
    pathname = "/",
    search = "",
    hash = "",
    state = null,
    

我尝试过的方法:再次安装 react-router-dom,将历史依赖项更新为版本 5.1.0

这是我的代码:

import { Router, Routes, Route, Link, NavLink } from 'react-router-dom'
import Home from './views/Home.jsx';

function App() {
  return (
    <Router>
      <div>
        <Link to="/home">Home</Link>
      </div>
      <Routes>
        <Route path="/home" element={<Home/>}/>
      </Routes>
    </Router>
  );
}

export default App;

这些是 package.json 的依赖项

history
"dependencies": {
    "@craco/craco": "^6.4.0",
    "@testing-library/jest-dom": "^5.15.0",
    "@testing-library/react": "^11.2.7",
    "@testing-library/user-event": "^12.8.3",
    "history": "^5.1.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^6.0.0",
    "react-scripts": "4.0.3",
    "web-vitals": "^1.1.2"
  }
2个回答

react-router-dom 的第 6 版与以前的版本相比有一些非常重大的重大变化。

虽然从 react-router-dom 导入 Router 并不常见,但即使在第 4/5 版中,您通常也会在较低级别的 Router 上导入 BrowserRouterHashRouterMemoryRouter 之一。

您问题的原因可以在 此处 的源代码中找到:

export function Router({
  basename: basenameProp = "/",
  children = null,
  location: locationProp,
  navigationType = NavigationType.Pop,
  navigator,
  static: staticProp = false
}: RouterProps): React.ReactElement | null {
  ...

  let {
    pathname = "/", // <-- attempt destructure from undefined
    search = "",
    hash = "",
    state = null,
    key = "default"
  } = locationProp;

  ...

通知这里 locationProp 正在被解构。如果您没有向 Router 组件提供 location 属性,则解构会失败。

请注意,在更高级别的路由器中,这些属性已为您实例化并传递。历史对象 ( navigation ) location 属性已为我们创建并传递。我们不需要自己管理这些。

BrowserRouter

export function BrowserRouter({
  basename,
  children,
  window
}: BrowserRouterProps) {
  let historyRef = React.useRef<BrowserHistory>();
  if (historyRef.current == null) {
    historyRef.current = createBrowserHistory({ window });
  }

  let history = historyRef.current;
  let [state, setState] = React.useState({
    action: history.action,
    location: history.location
  });

  React.useLayoutEffect(() => history.listen(setState), [history]);

  return (
    <Router
      basename={basename}
      children={children}
      location={state.location}
      navigationType={state.action}
      navigator={history}
    />
  );
}

如果您更喜欢使用 Router 组件,那么您需要自己创建并传递这些 props。

示例:

import { Router, Routes, Route, Link } from "react-router-dom";
import { createBrowserHistory } from "history";

const history = createBrowserHistory();

export default function App() {
  return (
    <Router location={history.location} navigator={history}>
      <div>
        <Link to="/home">Home</Link>
      </div>
      <Routes>
        <Route path="/home" element={<Home />} />
      </Routes>
    </Router>
  );
}

编辑 react-router-dom-throws-two-errors-when-reading-the-pathname-property

另一种选择,OFC,是只使用更高级别的路由器之一。

示例:

import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <div>
        <Link to="/home">Home</Link>
      </div>
      <Routes>
        <Route path="/home" element={<Home />} />
      </Routes>
    </Router>
  );
}
Drew Reese
2021-11-07

我找到了一个解决方案。安装以前版本的 react-router-dom 。我认为这是一个新的错误,所以我认为很多人会与上一个版本的 react 有同样的冲突。

Mauricio Ariza
2021-11-07