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

Javascript 如何在基于数组长度的条件渲染之前填充数组?,javascript,reactjs,redux,Javascript,Reactjs,Redux,我想在渲染之前填充一个数组,并且渲染是基于数组长度的有条件的 如果数组的长度>0,则进行渲染,否则不进行渲染 但是长度似乎总是0,因为useffect是异步的,所以渲染永远不会完成 下面是我的代码: function OrderDetail(props) { const {userInfo} = useSelector(state => state.user) const [order, setOrder] = useState({}); const [items,

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

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

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

下面是我的代码:

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>
function OrderDetail(道具){
const{userInfo}=useSelector(state=>state.user)
const[order,setOrder]=useState({});
const[items,setItems]=useState([]);
useffect(()=>{
如果(!userInfo){
道具。历史记录。推送(“/”)
返回
}
常量fetchOrderAndItems=async()=>{
//从后端获取订单。
const order=wait axios.get(“/api/orders/”+props.match.params.id{
标题:{
授权:“持票人”+userInfo.token
}
});
const order_data=order.data
setOrder(订单数据)
//取出订单中所有项目的id,从后端检索每个产品,
//将它们推入“项目数组”并将其设置为“项目”状态。
让项目_数组=[];
order_data.orderItems.forEach(异步(orderItem)=>{
const{data}=await axios.get(“/api/products/”+orderItem.productId);
项目\u数组推送(数据);
})
log(“items\u array.length:+items\u array.length”);
console.log(items\u数组);
集合项目(项目\数组);
}
fetchOrderAndItems();
},[userInfo]);
//对于处于“items”状态的每个项,返回一个元素。
const itemsHtml=items.map(item=>{
返回
要展示的东西。
})
//如果itemsHtml.length>0,则呈现{itemsHtml},否则显示“您的购物车为空”。
//但显示的总是“您的购物车是空的”
返回
名称
价格
数量
小计
{
itemsHtml.length是否大于0?
{itemsHtml}
:
你的车是空的。
}
“console.log”的两行输出为:

我们可以看到
items\u array
的长度是0,而其中有内容,我认为这是因为它是异步的

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

有人能教我怎么解决吗


感谢您应该将项目ID映射到GET请求和
承诺的数组中,而不是为每个项目进行映射。所有
请求都将映射到它们。
forEach
不会等待回调完成,这就是为什么在记录时数组为空,但在显示日志时会填充该数组的原因

Promise.all
将等待所有映射请求解析,然后再使用已解析项值数组进行解析

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

我没有试着理解你的异步逻辑,但你有一个更基本的问题:
itemsHtml>0
应该是
itemsHtml.length>0
@RobinZigmond Sry这是一个错误,我已经纠正了。但这篇文章中的问题并不是因为它。它很有效!非常感谢你!但我认为在此之前应该有一个
等待
e
axios
?请修改一下,然后我会接受你的回答~@powerseed这是一个隐含的承诺回报,无需等待,
承诺。所有的
都会这样做。更新了答案,并做了一些澄清。