【问题标题】:Uncaught (in promise) TypeError: myorders.map is not a functionUncaught (in promise) TypeError: myorders.map is not a function
【发布时间】:2022-01-04 16:28:44
【问题描述】:

我已尝试使用微调器来解决加载数据的延迟问题。 请让我知道哪里错了。我正在使用 MongoDB,服务器是我的本地服务器计算机。

import { useEffect, useState } from 'react';
import React from 'react';
import { Container, Row, Col, Button, Carousel, Spinner } from 'react-bootstrap';
import useAuth from '../../../Authorization/hooks/useAuth';
import '../../../Style/style.css';


const Order = () => {

    const { user, loading } = useAuth();
    const [myorders, setMyOrders] = useState({});
    const [singleItem, setSingleItem] = useState({});

    console.log(myorders);


    useEffect(() => {
        const url = `http://localhost:5000/myorders/?email=${user?.email}`
        fetch(url)
            .then(res => res.json())
            .then(data => setMyOrders(data))
    }, []);


    const handleDelete = (id) => {
        const proceed = window.confirm('Do you really want to remove this item!');

        if (proceed) {
            const url = `http://localhost:5000/cars/${id}`;
            fetch(url, {
                method: 'DELETE'
            })
                .then(res => res.json())
                .then(data => {
                    if (data.deletedCount > 0) {
                        alert('Deleted Successfully!');
                        const remainingUsers = myorders.filter(item => item._id !== id);
                        setMyOrders(remainingUsers);
                    }

                });
        }
    }

    const totalCar = myorders.length;

    if (loading) {
        return <Spinner animation="border" />
    }


    return (
        <Container>
            <Row>
                <Col lg={12}>
                    {
                        totalCar == 0 ?
                        // <Spinner animation="border" />

                            <h6>Please select any car.</h6>
                            :
                            <h6>There are {totalCar} cars waiting to go into your garage!</h6>
                    }

                        <Row>
                            <Col>
                                {
                                    myorders.map(order =>
                                        // {key={order._id}}
                                        <div className='order_items'>
                                            <Row>
                                                <Col lg={4}>
                                                    <div className='item_img'>
                                                        <Carousel>
                                                            <Carousel.Item>
                                                                <img
                                                                    className="d-block w-100"
                                                                    src={order.img[1]}
                                                                    alt="First Image"
                                                                />
                                                            </Carousel.Item>
                                                            <Carousel.Item>
                                                                <img
                                                                    className="d-block w-100"
                                                                    src={order.img[2]}
                                                                    alt="Second Image"
                                                                />
                                                            </Carousel.Item>
                                                            <Carousel.Item>
                                                                <img
                                                                    className="d-block w-100"
                                                                    src={order.img[3]}
                                                                    alt="Third Image"
                                                                />
                                                            </Carousel.Item>
                                                            <Carousel.Item>
                                                                <img
                                                                    className="d-block w-100"
                                                                    src={order.img[4]}
                                                                    alt="Third Image"
                                                                />
                                                            </Carousel.Item>
                                                            <Carousel.Item>
                                                                <img
                                                                    className="d-block w-100"
                                                                    src={order.img[5]}
                                                                    alt="Third Image"
                                                                />
                                                            </Carousel.Item>
                                                            <Carousel.Item>
                                                                <img
                                                                    className="d-block w-100"
                                                                    src={order.img[6]}
                                                                    alt="Third Image"
                                                                />
                                                            </Carousel.Item>
                                                        </Carousel>
                                                    </div>
                                                </Col>
                                                <Col lg={8}>

                                                    <div className='item_info'>
                                                        <h5>{order.name}</h5>
                                                        <h6>Price: ${order.price}</h6>
                                                        <h6>Location: {order.location}</h6>
                                                        <h6>Mileage: {order.mileage}</h6>
                                                        <h6>Fuel: {order.fuel}</h6>
                                                        <Button onClick={() => handleDelete(order._id)}>Remove</Button>
                                                        {/* <Button onClick={() => handlePay(order._id)}>Pay</Button> */}
                                                    </div>
                                                </Col>
                                            </Row>
                                        </div>
                                    )
                                }
                            </Col>
                        </Row>

                </Col>
            </Row>

        </Container>
    );
};


export default Order;

【问题讨论】:

  • myorders 以一个没有map 方法的(空)对象开始生命 - 在您加载数据后我们不知道它是什么!

标签: javascript node.js reactjs mongodb bootstrap-4


【解决方案1】:

您收到此错误是因为您尝试 .map 而不是数组,因为在文件的顶部您将其初始化为对象,所以第一次去渲染它不能映射它。

const [myorders, setMyOrders] = useState({});

应该是

const [myorders, setMyOrders] = useState([]);

【讨论】:

  • 这个我也试过了
  • 我也试过这个(const [myorders, setMyOrders] = useState([]);) 但结果相同。
【解决方案2】:

React 的黄金法则是“React 不会等待渲染”。因此,您在第一次渲染时对一个对象调用 Array map,因为您的 myOrders 属性是用一个对象初始化的,而 map 不存在于对象上,只有数组。

如果您首先使用空数组初始化 myOrders useState,例如:

const [myOrders, setMyOrders] = useState([])

然后地图将在那里,但不会在第一次渲染时运行,因为数组是空的。哪个好。这比崩溃要好。

然后,当您的订单进入并设置到 myOrders 时,React 将再次渲染,因为对 useState 的更改会导致重新渲染。

作为安全预防措施和对用户的 UI/UX 好处,您还可以在呈现表格并在其上运行地图之前检查 myOrders 中是否有任何内容。你的回报是这样的:

{ myOrders.length ? &lt;MyTable orders={ myOrders }/&gt; : &lt;p&gt;No Orders&lt;/p&gt; }

您也可以在当前示例中访问地图之前检查这一点,如下所示:

myOrders.length &amp;&amp; myOrders.map(order =&gt; ...等

【讨论】: