开发者问题收集

未捕获的类型错误:无法读取未定义的属性(读取“图像”)BookingCar.js

2022-01-14
716

APP.JS 导入'./App.css'; 从“react-router-dom”导入{BrowserRouter as Router,Routes,Route,Navigate}; 从“./pages/Home”导入Home; 从“./pages/Login”导入Login; 从“./pages/Register”导入Register; 从“./pages/BookingCar”导入BookingCar; 导入“antd/dist/antd.css”

function App() {
return (
 <Router>
   <Routes>
      <Route path='/' element={<Home/>}/> 
      <Route path="/login" element={<Login/>}></Route>
      <Route path="/register" element={<Register />}></Route>
      <Route path="/booking/:id" element={<BookingCar />}></Route>
   </Routes>
</Router>

);

导出默认应用程序;

BookingCar.js

import React, {useState,useEffect} from "react";
import { useDispatch, useSelector } from "react-redux";
import { getAllcars } from "../redux/action/carsAction";
import { useParams } from 'react-router-dom';
import Spinner from "../components/Spinner";
import DefaultLayout from "../components/DefaultLayout";
import  { Row, Col} from "antd";


export default function BookingCar({match}){

const { carid } = useParams();

const {cars} = useSelector(state => state.carsReducer)
const {loading} = useSelector(state => state.alertReducer)
const [car, setcar] = useState({})
const dispatch = useDispatch()


useEffect(() => {
    dispatch(getAllcars())
    if(cars.length>0){
        setcar(cars.find(o=>o._id === carid))
    }
}, [cars])

return(

    <DefaultLayout> 
         {loading  && (<Spinner/> )}
         <Row>
            <Col lg={10} sm={24} xs={24}>
                <img alt=""src={car.image} className="carimg"/>
                           
            </Col>
          
         </Row>
    </DefaultLayout> 
  
)

Home.js

import React, {useState,useEffect} from "react";
import { useDispatch, useSelector } from "react-redux";
import DefaultLayout from "../components/DefaultLayout";
import { getAllcars } from "../redux/action/carsAction";
import  { Button, Row, Col} from "antd";
import {Link} from "react-router-dom";
import Spinner from "../components/Spinner";
export default function Home(){

const {cars} = useSelector(state => state.carsReducer)
const {loading} = useSelector(state => state.alertReducer)
const dispatch = useDispatch()

useEffect(() => {
    dispatch(getAllcars())
}, [])

return(
   
    <DefaultLayout> 
         {loading === true && (<Spinner/> )}
        <Row justify="center" gutter={16} className="mt-5">
            {cars.map(car=>{
                return <Col lg={5} sm={24} xs={24}> 
                    <div className="car p-2 bs1 ">
                        <img alt=""src={car.image} className="carimg"/>
                        <div className="car-content d-flex align-items-center justify-content-between">
                            <div> 
                                <p>{car.name}</p> 
                                <p>{car.rentPerHour} Rent Per Hour</p> 
                            </div> 

                            <div> 
                                <button className="btn1 mt-2"><Link to={`/booking/${car._id}`}>Book now </Link></button> 
                              
                            </div>

                        </div> 
                    </div> 
                </Col> 
            })}
        </Row>
    </DefaultLayout> 
)

} 在 BookingCar.js 中,我尝试获取汽车详细信息(如 ID(图像)),但出现错误 所以请帮我解决这个问题。

2个回答

您尝试在加载/应用到状态之前访问 car 。在尝试使用之前,请先检查它是否存在 -

{car && (
  <Row>
    <Col lg={10} sm={24} xs={24}>
      <img alt=""src={car.image} className="carimg"/>
    </Col>
  </Row>
)}
larz
2022-01-14

carid 未定义,因为它不是已定义的路线参数 ( path="/booking/:id" ),因此 .find 函数返回 undefined

您具有有效的 car 初始状态

const [car, setcar] = useState({});

因此您应该能够从 car 中解构 ( car.image & <img alt=""src={car.image} className="carimg"/> ) 而不会出现问题。稍后,当通过 cardid 路线参数筛选 cars 时,就会出现问题。

useEffect(() => {
  dispatch(getAllcars());
  if (cars.length > 0) {
    setcar(cars.find(o => o._id === carid));
  }
}, [cars]);

array.find 如果未找到匹配项,则可能会返回 undefined ,因此 UI 应该处理该问题。路线匹配参数也 始终 是字符串,因此如果 _id 字段不是 "string" 类型,则严格相等将不起作用。尝试通过转换为字符串进行类型安全比较。

cars.find(o => String(o._id) === carid)

...

return (
  <DefaultLayout> 
    {loading  && <Spinner />}
    {car && (
      <Row>
        <Col lg={10} sm={24} xs={24}>
          <img alt=""src={car.image} className="carimg" />
        </Col>
      </Row>
    )}
  </DefaultLayout>
);

最后,您将路线匹配参数定义为 ":id" ,但在组件中解构 carid 。确保匹配参数匹配。

如果路由为:

<Route path="/booking/:id" element={<BookingCar />} />

使用 const { id } = useParams();

否则,更新路由参数以匹配代码:

<Route path="/booking/:carid" element={<BookingCar />} />

使用 const { car​​id } = useParams();

Drew Reese
2022-01-14