如何在JSX中访问异步POST请求获取的verifiedData数据?
问题解决:在JSX中访问异步请求获取的数据
核心逻辑
异步请求返回的是Promise对象,直接从async函数返回的值无法在JSX中直接读取,必须通过**React状态(useState)**存储数据,触发组件重新渲染后,JSX才能访问到最新数据。另外,await只是异步语法糖,不用它也能实现请求,但代码可读性会大幅下降。
具体实现方案
1. 用useState存储请求结果(推荐)
这是React处理异步数据的标准方式:
- 定义状态变量存储请求返回的数据
- 在
async函数中获取数据后更新状态 - JSX直接读取状态变量渲染内容
修改后的完整代码示例:
import { useState, useEffect } from 'react'; // 定义状态存储请求结果,初始值设为null const [verifiedData, setVerifiedData] = useState(null); // 可选:添加加载状态,提升用户体验 const [isLoading, setIsLoading] = useState(false); const handleVerifyData = async() => { setIsLoading(true); try { const verifyCall = await reservationsService.verifyQueueReservations(filteredReservationIds); // 将请求到的数据存入状态 setVerifiedData(verifyCall.data); } catch (err) { // 处理请求错误,比如提示用户 console.error('验证请求失败:', err); } finally { setIsLoading(false); } } // 可选:当Modal打开时自动触发请求 useEffect(() => { if (modals['carOnPlaceModal']?.isOpened) { handleVerifyData(); } }, [modals['carOnPlaceModal']?.isOpened]); // Modal部分直接使用verifiedData状态渲染 <Modal isOpen={modals['carOnPlaceModal']?.isOpened ?? false} onClose={handleClose} styles={{ width: "500px", bodyPadding: "28px 30px" }} > {isLoading ? ( <Text>加载中...</Text> // 加载状态提示 ) : verifiedData?.map(info => { // 原JSX渲染逻辑保持不变 return <Flex key={info.reservationId} style={{ flexDirection: "row", height: "40%", justifyContent: "space-evenly", alignItems: "flex-start" }}> <Flex style={{ display: "flex", flexDirection: "column" }}> <Text mb="10px">{info?.vehicleMark} {info?.vehicleModel} ({info?.vehicleBodyType})</Text> <CarNumberBox title={info.vehicleGovNumber} /> </Flex> <Flex style={{ display: "flex", flexDirection: "column" }}> <Text fontSize="base" mb="10px">{T("notifications.car_on_place.form.select_box")}</Text> <ChakraSelect value={selectedBoxes[info.reservationId]} onChange={async (e: any) => { const boxNumber: number = parseInt(e.target.value); const res: AxiosResponse<any> = await reservationsService.getCheckboxAvailability(info.reservationId, boxNumber); const updatedSelectedBoxes: any = { ...selectedBoxes }; const hasWarning: boolean = res.data?.data?.warning ?? false; const hasError: boolean = res.data?.data?.error ?? false; updatedSelectedBoxes[info.reservationId] = boxNumber; if (hasWarning) { toggleModal( "confirmationModal", true, { title: `დარწმუნებული ხართ, რომ გსურთ ${boxNumber} ბოქსის შეცვლა`, handleSubmit: () => { setSelectedBoxes(updatedSelectedBoxes) toggleModal("confirmationModal", false, { title: "" }) } } ) return; } if (hasError) { toast.error(T("general.error")) console.log('Warning for box'); return; } setSelectedBoxes(updatedSelectedBoxes); }} > {Array(info?.boxCount).fill(0).map((option: any, index: number) => { return <option key={index} value={index + 1}>#{index + 1}</option>; })} </ChakraSelect> </Flex> </Flex> })} </Modal>
2. 不用await的实现方式(不推荐)
可以用.then()链式调用替代await,但代码嵌套更深、可读性差,且仍需将数据存入状态:
const handleVerifyData = () => { setIsLoading(true); reservationsService.verifyQueueReservations(filteredReservationIds) .then(verifyCall => { setVerifiedData(verifyCall.data); }) .catch(err => { console.error('验证请求失败:', err); }) .finally(() => { setIsLoading(false); }); }
关键注意点
- 异步请求的结果必须存入React状态,否则组件无法感知数据变化并重新渲染
- 必须添加错误处理(
try/catch或.catch),避免请求失败导致页面崩溃 - 加载状态是可选但推荐的优化,能避免用户看到空白或旧数据
内容的提问来源于stack exchange,提问作者Nika
相关产品推荐
相关产品推荐

