React - TypeError:无法读取未定义的属性(读取“params”)

kir*_*iri 13 reactjs react-router react-router-dom

所以我收到一条错误消息 - TypeError: Cannot readproperties of undefined (reading 'params')

TypeError: Cannot read properties of undefined (reading 'params')
       5 | import products from '../products'
       6 | 
       7 | function ProductScreen({ match }) {
       8 |     const product = products.find((p) => p._id == match.params.id)
       9 |     return (
      10 |         <div>
      11 |             {product.name}
Run Code Online (Sandbox Code Playgroud)

这是我的 ProductScreen.js 文件,导致出现问题

import React from 'react'
import { Link } from 'react-router-dom'
import { Row, Col, Image, ListGroup, Button, Card } from 'react-bootstrap'
import Rating from '../components/Rating'
import products from '../products'

function ProductScreen({ match }) {
    const product = products.find((p) => p._id == match.params.id)
    return (
        <div>
            {product.name}
        </div>
    )
}

export default ProductScreen
Run Code Online (Sandbox Code Playgroud)

和我的 App.js

import { Container } from 'react-bootstrap'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import Header from './components/Header'
import Footer from './components/Footer'

import HomeScreen from './screens/HomeScreen'
import ProductScreen from './screens/ProductScreen'

function App() {
  return (
    <Router>
      <Header />
      <main className="py-3">
        <Container>
          <Routes>
            <Route path='/' element={<HomeScreen/>} exact />
            <Route path='/product/:id' element={<ProductScreen/>} />
          </Routes>
        </Container>
      </main>
      <Footer />
    </Router>
  );
}

export default App;
Run Code Online (Sandbox Code Playgroud)

我还尝试将 match.params.id 更改为 Number 或 ParseInt (match.params) 但仍然给我一个错误...

我知道这很简单,但我被困在这里,无法进一步...任何帮助将不胜感激!

还有一个问题 - 在 App.js 内部,即 Route 所在的位置,在教程中使用 Components={} 属性而不是 element={}。当我尝试同样的方法时,它给了我一个错误,所以我必须以另一种方式修复它。你知道为什么会导致错误吗?

来自教程

<Route path='/' component={HomeScreen} exact />
Run Code Online (Sandbox Code Playgroud)

我的解决办法——

<Route path='/' element={<HomeScreen/>} exact />
Run Code Online (Sandbox Code Playgroud)

Dre*_*ese 23

该教程似乎较旧,并且使用react-router-dom版本 5,而您使用的是版本 6。在版本 6 中,有许多重大 API 更改。组件Route不再使用componentprops render,而是element通过有效的 JSX 文字传递的 props 替换了它们。路由属性historylocationmatch)也不再存在,路由组件现在必须使用 React hooks 来访问它们。

路线与路线

interface RouteProps {
  caseSensitive?: boolean;
  children?: React.ReactNode;
  element?: React.ReactElement | null;
  index?: boolean;
  path?: string;
}
Run Code Online (Sandbox Code Playgroud)

给定路线:<Route path='/product/:id' element={<ProductScreen/>} />

使用useParams钩子访问id匹配参数。匹配参数将是一个字符串,因此如果您的产品 ID 是数字类型,则为了确保严格相等,请将属性转换_id为字符串以使用类型安全的比较。不要忘记,如果未找到匹配项,Array.prototype.find则返回undefined,因此代码应在渲染时尝试访问结果值之前检查结果值。

import { Link, useParams } from 'react-router-dom';
...

function ProductScreen() {
  const { id } = useParams();
  const product = products.find((p) => String(p._id) === id);

  if (!product) return null; // or fallback UI

  return (
    <div>
      {product.name}
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)


小智 7

我也遇到了同样的问题,最后这段代码起作用了。

import { useParams } from 'react-router-dom';

const { id } = useParams();

const product = products.find((p) => p._id === (id));

 <Route path="/product/:id" element={<ProductDetails />} />
Run Code Online (Sandbox Code Playgroud)


小智 0

在路由器中:

<Route path='/product/:id' element={ProductScreen} />
Run Code Online (Sandbox Code Playgroud)

在 ProductScreen 组件中:

import { useParams } from "react-router-dom";
...
const { id } = useParams();
Run Code Online (Sandbox Code Playgroud)

https://v5.reactrouter.com/web/api/Hooks/useparams