gpt4 book ai didi

javascript - 如何在基于数组长度的条件渲染之前填充数组?

转载 作者:行者123 更新时间:2023-12-04 09:44:44 25 4
gpt4 key购买 nike

我想在渲染之前填充一个数组,渲染是基于数组长度的条件。

如果数组的长度 > 0,则进行渲染,否则不进行。

但似乎长度总是 0 因为 useEffect是异步的,所以渲染永远不会完成。

下面是我的代码:

function OrderDetail(props) {
const {userInfo} = useSelector(state => state.user)
const [order, setOrder] = useState({});
const [items, setItems] = useState([]);

useEffect(()=>{
if(!userInfo){
props.history.push("/")
return
}

const fetchOrderAndItems = async () => {
// Get an order from backend.
const order = await axios.get("/api/orders/" + props.match.params.id, {
headers:{
authorization: "Bearer " + userInfo.token
}
});
const order_data = order.data
setOrder(order_data)

// Take out the id of all items in the order, retrieve each product from backend,
//push them in "items_array" and set it in the "items" state.
let items_array = [];
order_data.orderItems.forEach( async (orderItem) => {
const {data} = await axios.get("/api/products/" + orderItem.productId);
items_array.push(data);
})

console.log("items_array.length: " + items_array.length);
console.log(items_array);

setItems(items_array);
}

fetchOrderAndItems();
}, [userInfo]);

// For each item in the "items" state, return a <tr> element.
const itemsHtml = items.map(item => {
return <tr key={item._id}>
Something to display.
</tr>
})

// if itemsHtml.length > 0, render {itemsHtml}, otherwise display "Your cart is empty.".
// But what is displayed is always "Your cart is empty."
return <table className="table text-center">
<thead style={{border: "none"}}>
<tr>
<th style={{border: "none"}} scope="col"></th>
<th style={{border: "none"}} scope="col">Name</th>
<th style={{border: "none"}} scope="col">Price</th>
<th style={{border: "none"}} scope="col">Qty</th>
<th style={{border: "none"}} scope="col">Subtotal</th>
<th style={{border: "none"}} scope="col"></th>
</tr>
</thead>
{
itemsHtml.length > 0?
<tbody>
{itemsHtml}
</tbody>
:
<tbody>
<tr className="text-center">
<th className="text-center" scope="row" colSpan="6">Your cart is empty. </th>
</tr>
</tbody>
}
</table>

“console.log” 2 行的输出是:
enter image description here

我们可以看到 items_array的长度里面有内容时为0,我认为是因为它是异步的。

我猜因为长度是0,所以 itemsHtml.length > 0?的条件渲染永远不会为真,因此永远不会呈现所需的内容。

谁能教教我怎么解决?

谢谢

最佳答案

您应该将项目 ID 映射到一组 GET 请求和 Promise.all,而不是对项目进行 for-each'ing。他们。 forEach不等待回调完成,这就是为什么当您记录它时数组为空但在显示日志时填充的原因。
Promise.all将等待所有映射的请求解决,然后再使用已解决的项目值数组进行解决。

Promise.all(
order_data.orderItems.map(
({ productId }) => axios.get(`/api/products/${productId}`)
))
.then(results => setItems(results));

关于javascript - 如何在基于数组长度的条件渲染之前填充数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62184415/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com