javascript 我找不到错误TypeError:无法读取未定义的属性(阅读“name”)

pn9klfpd  于 2023-10-14  发布在  Java
关注(0)|答案(5)|浏览(145)

我是一个新的React,我需要一些帮助,当我试图把一些“产品”从一个数组的对象,我有一个文件,我的React应用程序称为“products.js”。
问题是,我可以在主屏幕中绘制阵列中的产品。然而,当我试图在我的详细信息产品页面上绘制这些产品时(这是一个我可以看到单个产品详细信息的页面)“ProductDetails.js”我得到了错误(无论我是否尝试使用product.name或product.price或其他):
TypeError:无法读取未定义的属性(阅读“name”)
为了让你对我所说的有一个概念,我将与你分享我的代码中的一些片段,以使你了解上下文。我将从确切的错误消息开始,并以我的项目管理的一瞥结束。

  • 错误信息 *
TypeError: Cannot read properties of undefined (reading 'name')
ProductDetails
C:/Users/jjimennz/OneDrive/Desktop/eCommerce MERN Stack/Sprint1/frontend/src/views/ProductDetails.js:19

 16 | const ProductDetails = ({ match }) => {
  17 |   const product = products.find((p) => p._id === match.params.id);
  18 | 
> 19 |   return <div>{product.name}</div>;
  20 | };
  21 | 
  22 | export default ProductDetails;
  • 这是我有麻烦的看法,不仅是与“product.name“我发生任何“产品.价格”“产品.图像”.这是产品细节屏幕,这个视图应该在它自己的页面上向我展示每个产品的细节,我称之为“ProductDetails.js”***
import React from "react";
import products from "../products";

const ProductDetails = ({ match }) => {
  const product = products.find((p) => p._id === match.params.id);

  return <div>{product.name}</div>;
};

export default ProductDetails;
  • 这是一个文件,其中包含我想在上面的产品详细信息屏幕上绘制的产品。这个文件名为“products.js”:*
const products = [
  {
    _id: 1,
    name: "Nemeziz 19.4",
    image:
      "https://assets.adidas.com/images/w_600,f_auto,q_auto/75987ad2e31644d59d24ab3000fce766_9366/Botines_Nemeziz_19.4_Pasto_Sintetico_Verde_FV3317_41_detail.jpg",
    description: "Breve descripcion de los zapatos",
    brand: "Adidas",
    category: "Zapatos",
    price: 89.99,
    countInStock: 20,
    rating: 4.5,
    numReviews: 14,
  },
  {
    _id: 2,
    name: "Adidas Ace",
    image: "https://www.sports-ws.com/img/item/F163AD0/F163AD0654.jpg",
    description: "Breve descripcion de los zapatos",
    brand: "Adidas",
    category: "Zapatos",
    price: 149.99,
    countInStock: 8,
    rating: 4.5,
    numReviews: 15,
  },
];

export default products
  • 这是主屏幕的视图,我在上面的数组中显示所有产品,这一个工作得很好,并在屏幕上绘制数组中的每个产品。这个叫做“HomeScreen.js”*
import React from "react";
import { Row, Col } from "react-bootstrap";
import Product from "../components/Product";
import products from "../products";

const HomeScreen = () => {
  return (
    <>
      <h1>Latest Products</h1>
      <Row>
        {products.map((product) => (
          <Col key={product._id} sm={12} md={6} lg={4} xl={3}>
            <Product product={product} />
          </Col>
        ))}
      </Row>
    </>
  );
};

export default HomeScreen;

*这是产品组件,它基本上是在上面的主屏幕视图中绘制阵列中的每个产品。这一个作为上面的主屏幕也工作得很好,它给我带来了它的名称,价格和形象的产品。我将此组件命名为“Product.js”

import React from "react";
import { Link } from "react-router-dom";
import { Card } from "react-bootstrap";
import Rating from "./Rating";

const Product = ({ product }) => {
  return (
    <Card className="my-3 p-3 rounded">
      <Link to={`/product/${product._id}`}>
        <Card.Img src={product.image} variant="top" />
      </Link>
      <Card.Body>
        <Link to={`/product/${product._id}`}>
          <Card.Title as="div">
            <strong>{product.name}</strong>
          </Card.Title>
        </Link>

        <Card.Text as="div">
          <Rating
            value={product.rating}
            text={`${product.numReviews} reviews`}
          />
        </Card.Text>
        <Card.Text as="h3">${product.price}</Card.Text>
      </Card.Body>
    </Card>
  );
};

export default Product;
  • “App.js”文件,以便您更好地了解我的项目中发生的事情 *
import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import { Container } from "react-bootstrap";
import Header from "./components/Header";
import Footer from "./components/Footer";
import HomeScreen from "./views/HomeScreen";
import ProductDetails from "./views/ProductDetails";

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

export default App;
  • 这是我的“package.json”文件,在我的项目中有依赖关系,以防万一它有助于帮助我解决这个问题 *
{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^11.2.7",
    "@testing-library/user-event": "^12.8.3",
    "react": "^17.0.2",
    "react-bootstrap": "^2.0.0",
    "react-dom": "^17.0.2",
    "react-router-bootstrap": "^0.25.0",
    "react-router-dom": "^5.3.0",
    "react-scripts": "4.0.3",
    "web-vitals": "^1.1.2"
  },
  "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"
    ]
  }
}
  • 这里有一个产品详细信息视图上错误消息的屏幕截图 *

  • 这里你有一个屏幕截图的网页,作品的主屏幕 *

uqxowvwt

uqxowvwt1#

您的问题是您的.find()方法返回undefined,因此您无法访问product上的属性,例如.name,因为它是undefined。当回调函数没有为数组中的任何项返回true值时,.find()方法将返回undefined
在这种情况下,只有当产品id与URL中使用的id完全匹配(在值和类型上)时,回调才会返回true

p._id === match.params.id

然而,上面的永远不会是true,因为数据中的p._idnumber类型,而match.params.idstring类型,所以在严格相等===下,两者永远不会被认为相等。结果,.find()永远找不到匹配,您得到undefind。相反,你可以使用“宽松”的相等比较==,它不需要类型匹配:

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

或者,您可以使用Number()等方法手动转换类型,并坚持使用===

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

其他尝试

我注意到这个问题已经引起了很多关注,所以我想我应该添加另一个常见的原因,为什么你可能会看到这个错误(注意这些原因不适用于OP代码)。
首先,这个错误意味着你使用.name的对象的值是undefined。通常情况下,如果您使用x1m19 n1x之类的东西进行API调用,或者在x1m20 n1x中执行其他异步任务,则会发生这种情况,这些任务设置了您正在使用x1m21 n1x的任何值。有两种方法可以解决这个问题,一种方法是使用optional chaining来防止访问.name属性,如果对象是nullundefined,例如:

<strong>{product?.name}</strong>

或者,另一种方法是分配状态值,使其最初不是未定义的,例如:

const [product, setProduct] = useState({}); // <-- using `product.name` now works, whereas doing `useState()` wouldn't work
yebdmbv4

yebdmbv42#

match.params.id类型的字符串,所以你应该解析字符串,因为_id作为int,你可以使用parseInt(1)

import React from "react";
    import products from "../products";

    const ProductDetails = ({ match }) => {
       const product = products.find((p) => p._id === parseInt(match.params.id));

       return <div>{product.name}</div>;
    };

    export default ProductDetails;

您可以查看完整文档https://reactrouter.com/web/api/match

lf3rwulv

lf3rwulv3#

Try this: Make changes in below two files only.

For ProductDetails.js

import React from "react";
import products from "../products";
import { useParams } from 'react-router-dom'

const ProductDetails = () => {
    const {id} = useParams()
    const product = products.find(p=>p._id === id)
    return <div>{product.name}</div>;
  
}

export default ProductDetails;

关于App.js

import React from "react";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import { Container } from "react-bootstrap";
import Header from "./components/Header";
import Footer from "./components/Footer";
import HomeScreen from "./views/HomeScreen";
import ProductDetails from "./views/ProductDetails";
function App() {
      return (
        <Router>
          <Header/>
          <main className='py-3'>
            <Container>
              <Routes> 
                <Route path ='/' element={<HomeScreen/>} exact />
                <Route path ='/product/:id' element={<ProductDetails/>}/>
              </Routes>
            </Container>
          </main>
          <Footer/>
        </Router>
      );
    }
    
    export default App;
kkbh8khc

kkbh8khc4#

试试这个代码。

import React from 'react'
    import products from '../products'
    import { useParams } from 'react-router-dom'

    function ProductDetails() {
        const { id } = useParams();
        const product = products.find((p) => Number(p._id) === Number(id));
        return (
            <div>
                {product.image}
            </div>
        )
    }
    
    export default ProductDetails
xmakbtuz

xmakbtuz5#

我在react native Expo项目中工作,当我运行命令'npx expo start'时,它显示此错误。我通过运行命令修复了它
npx expo start --reset-cache
它对我很有效,你也可以试试。

相关问题