【问题标题】:为什么 useMatch 在 React 路由器中不起作用?
【发布时间】:2022-01-23 14:43:09
【问题描述】:

我正在从"react-router-dom" 学习如何使用useMatch() 我收到以下错误,我的网页是空白的:

Uncaught TypeError: Cannot read properties of undefined (reading 'path')
    at matchPath (index.tsx:1148)
    at index.tsx:481
    at mountMemo (react-dom.development.js:15846)
    at Object.useMemo (react-dom.development.js:16219)
    at useMemo (react.development.js:1532)
    at useMatch (index.tsx:481)
    at About (About.js:7)
    at renderWithHooks (react-dom.development.js:14985)
    at mountIndeterminateComponent (react-dom.development.js:17811)
    at beginWork (react-dom.development.js:19049)

我的代码在下面

import React from "react"
import { useMatch  } from "react-router-dom"
import { Link, Route } from "react-router-dom"
import SinglePage from "./SinglePage"

const About = () => {
  const { url, path } = useMatch()
  console.log("hello usematch!", useMatch())
  return (
    <div>
      <ul>
        <li>
          <Link to={`${url}/about-app`}>About App</Link>
        </li>
        <li>
          <Link to={`${url}/about-author`}>About Author</Link>
        </li>
      </ul>
      <Route path={`${path}/:slug`}>
        <SinglePage />
      </Route>
    </div>
  )
}
export default About

下面是index.js 文件,我们可以在其中找到关于页面:

import React from "react";
import ReactDOM from "react-dom";
//component file
import TodoContainer from "./functionBased/components/TodoContainer";
import { Route, Routes, BrowserRouter as Router } from "react-router-dom";


//stylesheet
import "./functionBased/App.css";
import About from "./pages/About";
import NotMatch from "./pages/NotMatch";
//stylesheet
// import "./App.css"
ReactDOM.render(
  <React.StrictMode>
    <Router>
      <>
        <Routes>
          <Route exact path="/" element={<TodoContainer />} />
          <Route path="/about" element={<About />} />
          <Route path="*" element={<NotMatch />} />

        </Routes>
      </>
    </Router>
  </React.StrictMode>,
  document.getElementById("root")
);

我已经尝试通过 api docs 但不清楚为什么这不起作用以及如何使页面加载。我正在尝试在调用它的上下文中返回最近的当前路由匹配。

我对反应和router apis 很陌生。

非常感谢

【问题讨论】:

  • console.log("hello usematch!", useMatch()) 的输出是什么?
  • 嗨@TarunSharma 这只是一个错误。控制台日志中没有任何内容
  • 你可以试试console.log('url: ', url);console.log('path: ', path);,看看它打印了什么?还是在第一次调用 useMatch() 时发生错误?
  • 我尝试控制台日志 console.log('url: ', url); console.log('path: ', path) 但没有看到任何东西(我假设它与 userMatch() 的使用方式有关
  • 文档链接不正确。它指向另一个库,而不是 react-router-dom

标签: javascript reactjs react-router react-router-dom


【解决方案1】:

看来您正在使用来自react-router-domRouter,而不是来自react-location 库的那个,后者提供了您需要的useMatch() 钩子。

您需要使用来自react-locationRouter,然后通过location 属性传递ReactLocation 的实例,将&lt;Router&gt;react-location 库链接。我的依据是您在问题中链接到的文档。

你的index.js 应该看起来像

import React from "react";
import ReactDOM from "react-dom";
//component file
import TodoContainer from "./functionBased/components/TodoContainer";
import { ReactLocation, Router } from 'react-location';

//stylesheet
import "./functionBased/App.css";
import About from "./pages/About";
import NotMatch from "./pages/NotMatch";
//stylesheet
// import "./App.css"

const reactLocation = new ReactLocation();

const routes = [
       {
         path: '/',
         element: <TodoContainer />,
       },
       {
         path: '/about',
         element: <About />,
       },
       {
         element: <NotMatch />,
       },
     ];

ReactDOM.render(
  <React.StrictMode>
    <Router location={reactLocation}
     routes={routes}>
    </Router>
  </React.StrictMode>,
  document.getElementById("root")
);

This article 可能有助于消除在如何使用 react-router-domreact-location 方面的差异。

【讨论】:

    【解决方案2】:

    react-router-dom v6 中,useMatch 挂钩采用 必需 pattern 值,该值是表示路径的字符串 PathPattern 对象。

    useMatch

    declare function useMatch<ParamKey extends string = string>(
      pattern: PathPattern | string
    ): PathMatch<ParamKey> | null;
    

    路径模式

    interface PathPattern {
      path: string;
      caseSensitive?: boolean;
      end?: boolean;
    }
    

    据我所知,您似乎正在尝试使用与 v5 中相同的模式构建“嵌套”路由。这在 v6 中不一样,因为 v6 可以通过不指定以前导 "/" 开头的绝对路径来利用相对链接/路由。

    请参阅 v5 迁移指南中的 Relative Routes and Links

    应用相对链接/路由:

    const About = () => {
      return (
        <div>
          <ul>
            <li>
              <Link to="about-app">About App</Link>
            </li>
            <li>
              <Link to="about-author">About Author</Link>
            </li>
          </ul>
          <Route path=":slug">
            <SinglePage />
          </Route>
        </div>
      )
    }
    

    react-router-dom v6 现在也总是使用精确路径匹配,因此为了确保任何嵌套的Route 组件可以匹配和呈现,您应该更新较低的路径以允许子路由匹配。如果"/about" 正在渲染子路由,则附加一个通配符匹配器。

    应用程序

    <Router>
      <Routes>
        <Route exact path="/" element={<TodoContainer />} />
        <Route path="/about/*" element={<About />} />
        <Route path="*" element={<NotMatch />} />
      </Routes>
    </Router>
    

    【讨论】:

      猜你喜欢
      • 2020-05-21
      • 1970-01-01
      • 1970-01-01
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      • 2020-07-31
      • 1970-01-01
      相关资源
      最近更新 更多