React 路由无法在导航中读取路径名 属性

React routing cannot read pathname property on navigation

我最近开始使用 React 开发前端应用程序,并且我有一些使用 react-native 的编程经验。 为了提高我对 React 的了解,我研究了官方文档并参加了 udemy 的课程。 所以我正在构建一个小型测试应用程序,在其中使用反应路由(按照我们在 udemy 课程中看到的内容)。 但是,我有以下与路由相关的错误(我附上错误屏幕)

我在网上的堆栈上搜索了可能的解决方案,比如降级react-router-dom,或者修改历史声明,但不幸的是我仍然得到这个错误,我无法理解它来自什么。 您有什么建议或建议吗?

我的应用配置:


  "name": "app1",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@reduxjs/toolkit": "^1.8.1",
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^12.1.4",
    "@testing-library/user-event": "^13.5.0",
    "history": "^5.3.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "react-redux": "^7.2.8",
    "react-router": "^6.3.0",
    "react-router-dom": "^6.3.0",
    "react-scripts": "5.0.0",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

import React, { Component } from 'react';

import Component1 from './functional/component1';
import Component2 from './functional/component2';
import Component3 from './functional/component3';

//import container home-page
import Container1 from './containers/container1';
import Header from './containers/header';
import history from './utils/history';

//react router import
import { Router, Route } from 'react-router';

class Routes extends Component {
   render() {
      return (
         <div>
            <Router history={history.location} navigator={history} >
               <div>
                  <Header />
                  <Route path="/" component={Container1} />
                  <Route path="/component1" component={Component1} />
                  <Route path="/component2" component={Component2} />
                  <Route path="/component3" component={Component3} />
               </div>
            </Router>
         </div>
      )
   }
}

export default Routes;

-history.js

var createHistory = require('history').createBrowserHistory;
export default createHistory();

您正在使用 react router v6,在 v6 中,您必须将所有 route's 包装在 <Routes>...</Routes> 标签中。

//react router import
import { Router, Route, Routes } from 'react-router'; // Make sure to import ----Routes----

class Routes extends Component {
   render() {
      return (
         <div>
            <Router history={history.location} navigator={history} >
               <div>
                  <Header />
                  <Routes>
                    <Route path="/" component={Container1} />
                    <Route path="/component1" component={Component1} />
                    <Route path="/component2" component={Component2} />
                    <Route path="/component3" component={Component3} />
                  </Routes>
               </div>
            </Router>
         </div>
      )
   }
}

export default Routes;

你不能在 <Routes>...</Routes> 之间添加任何东西,除了 <Route />

问题

low-level Router 使用了一些与 v5 中不同的道具。

Router

declare function Router(
  props: RouterProps
): React.ReactElement | null;

interface RouterProps {
  basename?: string;
  children?: React.ReactNode;
  location: Partial<Location> | string; // <-- required
  navigationType?: NavigationType;
  navigator: Navigator;                 // <-- required
  static?: boolean;
}

Router source

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

  let {
    pathname = "/", // <-- cannot read "pathname" of undefined!
    search = "",
    hash = "",
    state = null,
    key = "default",
  } = locationProp;

  ...

  if (location == null) {
    return null;
  }

  return (
    <NavigationContext.Provider value={navigationContext}>
      <LocationContext.Provider
        children={children}
        value={{ location, navigationType }}
      />
    </NavigationContext.Provider>
  );
}

您错误地使用了 history 属性而不是 location 属性,这就是为什么 location 在组件中未定义并且无法读取 pathname 的原因.

此外,在 react-router-dom@6 中,Route 组件必须包含在 Routes 组件中,以便路由路径匹配和渲染工作。

解决方案

传递正确的必需道具并将 Route 组件包装在 Routes 组件中。

import React, { Component } from 'react';

import Component1 from './functional/component1';
import Component2 from './functional/component2';
import Component3 from './functional/component3';

//import container home-page
import Container1 from './containers/container1';
import Header from './containers/header';
import history from './utils/history';

//react router import
import { Router, Routes, Route } from 'react-router';

class Routes extends Component {
  render() {
    return (
      <div>
        <Router location={history.location} navigator={history} >
          <div>
            <Header />
            <Routes>
              <Route path="/" component={Container1} />
              <Route path="/component1" component={Component1} />
              <Route path="/component2" component={Component2} />
              <Route path="/component3" component={Component3} />
            </Routes>
          </div>
        </Router>
      </div>
    )
  }
}