使用 React 的 Promises 时的实现问题

Implementation problems while using React's Promises

我正在处理一项需要实施订单管理系统的任务。问题是我需要进行 GET 调用以获取所有订单,并且对于每个订单我都需要进行另一个 GET 调用以便我可以获得该订单的项目。 我的问题是如何在呈现所有内容之前进行这些调用并创建一些订单和项目的数据结构。 我尝试使用 async/await 但我无法在呈现所有内容之前创建订单及其相关项目的数据结构。

现在我只处理订单 GET 调用

async componentDidMount() {
        const orders = await api.getOrders()
        this.setState({
            orders
        });
    }

我还为 returns 一个 Promise

项的 GET 调用创建了一个函数
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 和数量的数组

你可以试试这个 solution.I 被困在同一个问题几天 ago.So 它所做的是 setState 在 createItemsList 函数之后呈现 运行

async componentDidMount() {
            const orders = await api.getOrders()
            this.setState({
                orders
            }),
        
            () => this.createItemsList()
    }

我建议你将数据检索移动到每个组件中。

勾选sandbox here

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",
      qty: 1
    },
    {
      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 />;
}

在外部创建一个单独的方法来获取您需要的数据。

首先从API获取订单。然后遍历每个订单并为每个项目再次调用 api 。 Await Promise.all 等待订单中的每个项目完成,然后将结果连接到一个数组,您可以在其中存储所有获取的项目。然后在循环完成后 return 结果数组。

在您的 componentDidMount 中调用此方法并根据承诺的结果更新状态 returned。

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.
        )}
    )
}