开发者问题收集

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

2021-12-09
61853

所以我收到一条错误消息 - TypeError:无法读取未定义的属性(读取“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}

这是我的 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

和我的 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;

我还尝试将 match.params.id 更改为 Number 或 ParseInt(match.params),但仍然出现错误...

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

还有一个问题 - 在 App.js 内部,Route 所在的位置,在教程中使用 components={} 属性而不是 element={}。当我尝试相同操作时,它出现错误,因此我不得不以另一种方式修复它。您知道为什么会导致错误吗?

来自教程

<Route path='/' component={HomeScreen} exact />

我的修复 --

<Route path='/' element={<HomeScreen/>} exact />
3个回答

本教程似乎比较旧,使用的是 react-router-dom 版本 5,而您使用的是版本 6。版本 6 中有许多重大 API 更改。 Route 组件不再使用 componentrender 属性,传递有效 JSX 文字的 element 属性取代了它们。 路由属性 ( historylocationmatch ) 也不再存在,路由组件现在 必须 使用 React 钩子来访问它们。

路由和路由

interface RouteProps {
  caseSensitive?: boolean;
  children?: React.ReactNode;
  element?: React.ReactElement | null;
  index?: boolean;
  path?: string;
}

给定路由: <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>
  );
}
Drew Reese
2021-12-09

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

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

const { id } = useParams();

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

 <Route path="/product/:id" element={<ProductDetails />} />
Sachin Pradhan
2022-01-16
import { Link, useParams } from "react-router-dom";
    ...
    
    function ProductScreen() {
      const { id } = useParams();
      const product = products.find((p) => p._id === id);
      return <div>{product.name}</div>;
    }
    
    export default ProductScreen;
antoniodenaro
2022-04-26