React项目如何将reducer中fetch异常在组件展示Bootstrap提示
实现方案
你需要调整getReportPDF方法使其能将异常状态传递到调用方组件,同时在组件内添加状态控制自定义提示的展示,具体实现步骤如下:
第一步:改造report-reducer.ts中的getReportPDF方法
将原有方法改为返回Promise,在异常分支返回错误状态,正常分支返回成功状态,方便组件侧捕获处理:
export const getReportPDF = (search, sort): Promise<{ success: boolean; msg?: string }> => { const params = new URLSearchParams(search) ? new URLSearchParams(search).toString() : null; const sorting = new URLSearchParams(sort) ? new URLSearchParams(sort).toString() : null; const requestUrl = `${apiUrlPDF}?${params}${Object.keys(sort).length > 0 ? '&' + sorting : ''}`; // 返回整个fetch调用链,把状态暴露给调用方 return fetch(requestUrl) .then(response => response.blob()) .then(blob => { if (blob.type === 'application/problem+json') { // 异常分支返回错误状态和提示信息 return { success: false, msg: '暂无符合条件的报告可导出' } } else { const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'report.pdf'; a.click(); window.URL.revokeObjectURL(url); // 补充内存释放逻辑,避免内存泄漏 return { success: true } } }) .catch(error => { console.log('error is ', error) return { success: false, msg: '导出失败,请稍后重试' } }); };
你提到的
if (blob.type === 'application/problem+json')分支确实需要返回特定标识,我们这里通过返回带success状态的对象来告知调用方导出结果,你也可以根据需求把后端返回的具体错误信息从blob中解析出来替换自定义提示文本。
第二步:在report.tsx组件内添加提示相关状态和渲染逻辑
新增状态控制提示的显隐和内容,调用导出方法时捕获状态控制提示展示:
import { useState } from 'react'; // 组件内部代码 const ReportPage = () => { // 新增提示控制状态 const [showExportAlert, setShowExportAlert] = useState(false); const [alertContent, setAlertContent] = useState(''); // 原有点击逻辑改造 const handleBtnClick = async () => { if (buttonClick === 'pdf') { const exportRes = await getReportPDF(params, sort); if (!exportRes.success) { // 导出失败时更新状态展示提示 setAlertContent(exportRes.msg); setShowExportAlert(true); // 可选配置:3秒后自动关闭提示 setTimeout(() => setShowExportAlert(false), 3000); } } } return ( <div className="report-page"> {/* 原有组件渲染内容 */} {/* 自定义Bootstrap风格提示,仅状态为true时渲染 */} {showExportAlert && ( <div class="alert alert-primary alert-dismissible fade show" role="alert"> {alertContent} <button type="button" class="btn-close" aria-label="Close" onClick={() => setShowExportAlert(false)} ></button> </div> )} </div> ) }
内容的提问来源于stack exchange,提问作者Jack23
相关产品推荐
相关产品推荐

