ReactJS中如何使用useState正确渲染订单接口数据
问题原因
接口返回的订单数据中,items字段是经过JSON序列化的字符串,不是可直接遍历的数组类型,直接对字符串做展开操作会被拆分为单个字符,无法获取到正确的商品对象,导致原有状态更新逻辑失效。另外现有代码的加载状态判断逻辑写反,会导致渲染异常。
修复步骤
- 处理接口响应时,先对每条订单的
items字段做JSON.parse()转换,拿到真正的商品数组后,再按需求合并到状态中 - 修正加载状态的渲染逻辑:加载中展示占位骨架,加载完成后再渲染真实商品数据
- 接口请求报错时也要关闭加载状态,避免页面一直处于加载态
- 不同订单可能存在相同id的商品,拼接唯一key避免React渲染告警
修正后的完整代码
import React from 'react'; import axios from "axios"; import {Card} from "../components/Card"; export const Orders = () => { const [orders, setOrders] = React.useState([]); const [isLoading, setIsLoading] = React.useState(true); React.useEffect(() => { async function fetchData() { try { const {data} = await axios.get('http://localhost:4000/api/orders'); // 解析items字符串,拍平所有商品 const formatOrders = data.reduce((prev, order) => { const itemsArr = JSON.parse(order.items); return [...prev, ...itemsArr]; }, []); setOrders(formatOrders); setIsLoading(false); } catch (error) { console.log(error); setIsLoading(false); } } fetchData(); }, []); return ( <div className="content"> <div className="content-header"> <h1>My orders</h1> </div> <div className="sneakers"> {isLoading ? ( // 加载状态渲染占位骨架 [...Array(8)].map((_, idx) => <Card key={`skeleton-${idx}`} loading={true} />) ) : ( orders.map(item => ( <Card key={`${item.id}-${item.title}`} id={item.id} title={item.title} price={item.price} image={item.image} loading={false} /> )) )} </div> </div> ) }
如果你后续需要按订单分组展示、显示每笔订单的交易日期,就不要把商品拍平,直接存储解析完
items字段的原始订单数组,渲染时先遍历订单,给每个订单加日期标题,再遍历订单下的商品渲染卡片即可。
内容的提问来源于stack exchange,提问作者markelov
相关产品推荐
相关产品推荐

