我正在尝试从 api 获取数据并将其呈现到屏幕,但我只能呈现最后的数据而不是所有 api 响应
I'm trying to get data from api and render it to the screen but I can render only last data not all api response
App.tsx
export interface Hotel {
id: string;
name: string;
address1: string;
address2: string;
starRating: number;
images: string[];
longDescription: string;
}
export interface Room {
id: string;
name: string;
longDescription: string;
}
const App: React.FC = () => {
const [hotels, setHotels] = useState<Hotel[]>([]);
const [rooms, setRooms] = useState<Room[]>([]);
useEffect(() => {
const getDetails = async () => {
const hotel = await axios.get<Hotel[]>(`${uri}`);
console.log(hotel.data);
const response = hotel.data.map(async (i) => {
const data = await (await fetch(`${uri}/${i.id}`)).json();
return data;
});
Promise.all(response).then((fetchedData) => {
const roomData = fetchedData.map((i) => {
return i.rooms;
});
console.log(roomData);
setRooms(roomData);
});
};
getDetails();
}, []);
return (
<div>
<GlobalStyle />
<HotelCard hotels={hotels} rooms={rooms} />-
</div>
);
};
HotelCard.TSX仅用于渲染带房间的酒店卡片。
interface HotelListProps {
hotels: Hotel[];
rooms: Room[];
}
const HotelCard: React.FC<HotelListProps> = ({ hotels, rooms }) => {
return (
<div>
{hotels.map((hotel) => (
<div key={hotel.id}>
<h1>{hotel.id}</h1>
// more code
</div>
))}
{rooms.map((room) => (
<div key={room.id}>
<h1>{room.name}</h1>
// more here...
</div>
))}
</div>
);
};
export default HotelCard;
console.log(roomData)
结果是
(4) [Array(8), Array(6), Array(9), Array(11)] 0: (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] 1: (6)
[{…}, {…}, {…}, {…}, {…}, {…}] 2: (9) [{…}, {…}, {…}, {…}, {…}, {…},
{…}, {…}, {…}] 3: (11) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…},
{…}, {…}] length: 4 [[Prototype]]: Array(0)
当我尝试渲染房间状态时,我只得到最后一个结果不完整。
根据您的日志,roomData 是一个数组数组。
您可以修改 Promise.all(...) 中的代码片段,将 roomData 作为对象数组:
let roomData = [];
fetchedData.forEach((i) => {
roomData = [...roomData, ...i.rooms];
});
两件事...
- 你没有打电话给
setHotels
所以你的 hotels
状态永远不会改变
- 假设每个 hotel 响应都有一个
rooms
数组,roomData
将成为一个数组数组,而不是您的组件期望的平面数组
我也会坚持使用 Axios(因为您已经安装了它)而不是混用 fetch()
const { data: hotels } = await axios.get<Hotel[]>(uri);
const allRooms = await Promise.all(hotels.map(async ({ id }) => {
// don't forget to provide a type for the response
const { data: { rooms } } = await axios.get<{ rooms: Room[] }>(
`${uri}/${encodeURIComponent(id)}`
);
return rooms;
}));
setHotels(hotels);
setRooms(allRooms.flat()); // flatten the array
App.tsx
export interface Hotel {
id: string;
name: string;
address1: string;
address2: string;
starRating: number;
images: string[];
longDescription: string;
}
export interface Room {
id: string;
name: string;
longDescription: string;
}
const App: React.FC = () => {
const [hotels, setHotels] = useState<Hotel[]>([]);
const [rooms, setRooms] = useState<Room[]>([]);
useEffect(() => {
const getDetails = async () => {
const hotel = await axios.get<Hotel[]>(`${uri}`);
console.log(hotel.data);
const response = hotel.data.map(async (i) => {
const data = await (await fetch(`${uri}/${i.id}`)).json();
return data;
});
Promise.all(response).then((fetchedData) => {
const roomData = fetchedData.map((i) => {
return i.rooms;
});
console.log(roomData);
setRooms(roomData);
});
};
getDetails();
}, []);
return (
<div>
<GlobalStyle />
<HotelCard hotels={hotels} rooms={rooms} />-
</div>
);
};
HotelCard.TSX仅用于渲染带房间的酒店卡片。
interface HotelListProps {
hotels: Hotel[];
rooms: Room[];
}
const HotelCard: React.FC<HotelListProps> = ({ hotels, rooms }) => {
return (
<div>
{hotels.map((hotel) => (
<div key={hotel.id}>
<h1>{hotel.id}</h1>
// more code
</div>
))}
{rooms.map((room) => (
<div key={room.id}>
<h1>{room.name}</h1>
// more here...
</div>
))}
</div>
);
};
export default HotelCard;
console.log(roomData)
结果是
(4) [Array(8), Array(6), Array(9), Array(11)] 0: (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] 1: (6) [{…}, {…}, {…}, {…}, {…}, {…}] 2: (9) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] 3: (11) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] length: 4 [[Prototype]]: Array(0)
当我尝试渲染房间状态时,我只得到最后一个结果不完整。
根据您的日志,roomData 是一个数组数组。 您可以修改 Promise.all(...) 中的代码片段,将 roomData 作为对象数组:
let roomData = [];
fetchedData.forEach((i) => {
roomData = [...roomData, ...i.rooms];
});
两件事...
- 你没有打电话给
setHotels
所以你的hotels
状态永远不会改变 - 假设每个 hotel 响应都有一个
rooms
数组,roomData
将成为一个数组数组,而不是您的组件期望的平面数组
我也会坚持使用 Axios(因为您已经安装了它)而不是混用 fetch()
const { data: hotels } = await axios.get<Hotel[]>(uri);
const allRooms = await Promise.all(hotels.map(async ({ id }) => {
// don't forget to provide a type for the response
const { data: { rooms } } = await axios.get<{ rooms: Room[] }>(
`${uri}/${encodeURIComponent(id)}`
);
return rooms;
}));
setHotels(hotels);
setRooms(allRooms.flat()); // flatten the array