开发者问题收集

未捕获的类型错误:无法读取未定义的属性(读取‘img’)

2022-03-31
897

ProductDetail.js 文件

import React from 'react'
import { useParams } from 'react-router-dom'
import DATA from '../Data';

const ProductDetail = () => {
  {/*Now we need a product id which is pass from the product page*/}
  const proid=useParams();
  const proDetail=DATA.filter(x=>x.id===proid.id)
  const product=proDetail[0]
  console.log(product)

  return (
    <>
      <div className='container my-5 py-3'>
        <div className='row'>
          <div className='col-md-6'>
            <img src={product.img} alt={product.title} />
          </div>
          <div className="col-md-6">
            <h1>{product.title}</h1>
            <hr />
            <h2>{product.price}</h2>
            <p>{product.desc}</p>
            <button className='btn btn-outline-primary'>Add to cart</button>
          </div>
        </div>
      </div>
    </>
  )
}

export default ProductDetail

App.js 文件

import './App.css';
import Header from './components/Header';
import {BrowserRouter, Routes,Route} from 'react-router-dom'
import Home from './components/Home';
import Product from './components/Product';
import About from './components/About';
import Contact from './components/Contact';
import Footer from './components/Footer';
import ProductDetail from './components/ProductDetail';


function App() {
  return (
    <div>
      <BrowserRouter>
        <Header/>
        <Routes>
          <Route path='/' element={<Home/>}/>
          <Route path='/product' element={<Product/>}/>
          <Route path='/product/:id' element={<ProductDetail/>}/>
          <Route path='/about' element={<About/>}/>
          <Route path='/contact' element={<Contact/>}/>
        </Routes>
        <Footer/>
      </BrowserRouter>
    </div>
  );
}

export default App;

Data.js 文件

const DATA=[
    {
        id: 0,
        title: 'Apple iPhone 11',
        price: 49900,
        desc: '6.1-inch (15.4 cm diagonal) Liquid Retina HD LCD display Water and dust resistant (2 meters for up to 30 minutes, IP68) Dual-camera system with 12MP Ultra Wide and Wide cameras; Night mode, Portrait mode, and 4K video up to 60fps 12MP TrueDepth front camera with Portrait mode, 4K video, and Slo-Mo Face ID for secure authentication A13 Bionic chip with third-generation Neural Engine Fast-charge capable',
        img: '/iphone1.jpg'
    },
    {
        id: 1,
        title: 'Apple iPhone 12 (128GB) - Blue',
        price: 58999,
        desc: '6.1-inch (15.5 cm diagonal) Super Retina XDR display Ceramic Shield, tougher than any smartphone glass A14 Bionic chip, the fastest chip ever in a smartphoneAdvanced dual-camera system with 12MP Ultra Wide and Wide cameras; Night mode, Deep Fusion, Smart HDR 3, 4K Dolby Vision HDR recording 12MP TrueDepth front camera with Night mode, 4K Dolby Vision HDR recording.Industry-leading IP68 water resistance.Supports MagSafe accessories for easy attach and faster wireless charging.iOS with redesigned widgets on the Home screen, all-new App Library, App Clips and more',
        img: '/blueapple.jpg'
    },
    {
        id: 2,
        title: 'Apple iPhone 11 (64GB) - (Product) RED',
        price: 47999,
        desc: '6.1-inch (15.4 cm diagonal) Liquid Retina HD LCD display Water and dust resistant (2 meters for up to 30 minutes, IP68).Dual-camera system with 12MP Ultra Wide and Wide cameras; Night mode, Portrait mode, and 4K video up to 60fps. 12MP TrueDepth front camera with Portrait mode, 4K video, and Slo-Mo Face ID for secure authentication.A13 Bionic chip with third-generation Neural EngineFast-charge capable',
        img: '/red.jpg'
    }
]

export default DATA
3个回答

您还可以使用可选链接来检查现有属性。

https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Optional_chaining

{<img src={product?.img} alt={product.title} />}
Felipe Souza
2022-03-31

问题

组件中的 path='/product/:id' id 路径参数将为字符串类型。

const { id } = useParams(); // <-- id is a String

DATA 中的 id 属性为数字类型。

const DATA = [
  {
    id: 0, // <-- id is a Number
    ...
  },
  {
    id: 1, // <-- id is a Number
    ...
  },
  {
    id: 2, // <-- id is a Number
    ...
  }
]

此类型不匹配导致 ProductDetail 组件中的严格 === 相等性检查失败。

const proid = useParams();
const proDetail = DATA.filter(x => x.id === proid.id); // returns empty array
const product = proDetail[0]: // undefined
console.log(product);

首次尝试访问未定义的属性 X 时会抛出错误。

<img
  src={product.img} // <-- first access throws error!!
  alt={product.title}
/>

解决方案

要使用严格 === 相等性,请确保您使用的是类型安全比较。您应将所有值转换为字符串。您还应该妥善处理数据中找不到产品的情况。

示例:

const ProductDetail = () => {
  const { id } = useParams();
  const product = DATA.find(x => String(x.id) === id);
  console.log(product);

  return (
    <div className='container my-5 py-3'>
      <div className='row'>
        {product
          ? (
            <>
              <div className='col-md-6'>
                <img src={product.img} alt={product.title} />
              </div>
              <div className="col-md-6">
                <h1>{product.title}</h1>
                <hr />
                <h2>{product.price}</h2>
                <p>{product.desc}</p>
                <button className='btn btn-outline-primary'>
                  Add to cart
                </button>
              </div>
            </>
          )
          : (
            <div className='col-md-12'>
              No product matched
            </div>
          )
        }
      </div>
    </div>
  );
};
Drew Reese
2022-03-31

您可能需要使用对象解构:

const {proid} = useParams();
vhbazan
2022-03-31