问题描述
我正在做一个需要实施订单管理系统的任务。问题是我需要进行GET调用才能获取所有订单,并且对于每个订单,我都需要进行另一个GET调用,以便可以获取此订单的商品。 我的问题是,在呈现所有内容之前,如何进行这些调用并创建订单和项目的某些数据结构。 我尝试使用async / await,但在呈现所有内容之前无法创建订单及其相关项目的数据结构。
目前,我只处理GET呼叫的订单
async componentDidMount() {
const orders = await api.getorders()
this.setState({
orders
});
}
我还为商品的GET调用创建了一个函数,该函数返回Promise
createItemsList = (order: Order) => {
let a = order.items.map((item) => {
return api.getItem(item.id);
});
return Promise.all(a);
};
有人建议将两者结合起来吗?预先感谢!
***编辑*** 这是我渲染订单的代码的一部分
{filteredOrders.map((order) => (
<div className={'orderCard'}>
<div className={'generalData'}>
<h6>{order.id}</h6>
<h4>{order.customer.name}</h4>
<h5>Order Placed: {new Date(order.createdDate).toLocaleDateString()},At: {new Date(order.createdDate).toLocaleTimeString()}</h5>
</div>
<Fulfilment order={order}/>
<div className={'paymentData'}>
<h4>{order.price.formattedTotalPrice}</h4>
<img src={App.getAssetByStatus(order.billingInfo.status)}/>
</div>
<ItemsList subItemsList={order.items} api={api}/>
</div>
))}
在组件ItemsList中,我呈现特定订单的商品,而order.items不是商品本身,而是我在每个订单中获得的商品ID和数量的数组
解决方法
我建议您将数据检索移到每个组件中。
import React,{ PureComponent } from "react";
const fakeOrderItems = {
1: [
{
id: 1,name: "Ramen",qty: 1
},{
id: 1,name: "Beer",qty: 1
}
],2: [
{
id: 1,name: "Steak",{
id: 2,name: "Iced Tea",qty: 1
}
]
};
const fakeOrders = [
{
id: 1,name: "Table 1",totalItems: 2
},{
id: 2,name: "Table 3",totalItems: 2
}
];
const fakeApi = {
getOrders() {
return new Promise((resolve) =>
setTimeout(() => resolve(fakeOrders),3000)
);
},getOrderItems(id) {
return new Promise((resolve) =>
setTimeout(() => resolve(fakeOrderItems[id]),3000)
);
}
};
class OrderItem extends PureComponent {
render() {
const { id,name,qty } = this.props;
return (
<div style={{ marginBottom: 10 }}>
<span>
{id}. {name} qty:{qty}
</span>
</div>
);
}
}
class OrderItemList extends PureComponent {
state = {
orderItems: []
};
componentDidMount() {
fakeApi
.getOrderItems(this.props.orderId)
.then((orderItems) => this.setState({ orderItems }));
}
render() {
const { orderItems } = this.state;
if (!orderItems.length) {
return <span>Loading orderItems...</span>;
}
return orderItems.map((item) => (
<OrderItem key={item.id + item.name} {...item} />
));
}
}
class Order extends PureComponent {
render() {
const { id,name } = this.props;
return (
<div style={{ marginBottom: 10 }}>
<div>
<span>Order #{id}</span>
</div>
<div>
<span>For table {name}</span>
</div>
<OrderItemList orderId={id} />
</div>
);
}
}
class OrderList extends PureComponent {
state = {
orders: []
};
componentDidMount() {
fakeApi.getOrders().then((orders) => this.setState({ orders }));
}
render() {
const { orders } = this.state;
if (!orders.length) {
return <div>Loading orders...</div>;
}
return orders.map((order) => <Order key={order.id} {...order} />);
}
}
export default function App() {
return <OrderList />;
}
,
您可以尝试此解决方案。几天前我也遇到了同样的问题。所以它的作用是在运行createItemsList函数后setState呈现
async componentDidMount() {
const orders = await api.getOrders()
this.setState({
orders
}),() => this.createItemsList()
}
,
在外部创建一个单独的方法来获取所需的数据。
首先从API获取订单。然后遍历每个订单,并再次为每个项目调用api。等待Promise.all
等待顺序完成每个项目,然后将结果连接到一个数组,在其中存储所有提取的项目。然后,在循环完成之后,返回结果数组。
在您的componentDidMount
中调用此方法,并根据承诺返回的结果更新状态。
state = {
orders: []
}
async getOrderItems() {
let orderItems = [];
const orders = await api.getOrders()
for (const order of orders) {
const items = await Promise.all(
order.items.map((item) => api.getItem(item.id))
)
orderItems = [...orderItems,...items]
}
return orderItems
}
componentDidMount() {
this.getOrderItems().then(orders => {
this.setState({
orders
})
})
}
render() {
if (this.state.orders.length === 0) {
return null
}
return (
{this.state.orders.map(order => (
// Render content.
)}
)
}