React中useState初始为空时Power BI报表无法渲染的问题求助
Power BI React嵌入报表:空初始值导致无法渲染的解决方案
问题根源
初始渲染时reportId和embedUrl为空字符串,<PowerBIEmbed>组件拿到无效配置后初始化失败,后续props更新时组件不会自动重新触发嵌入流程,导致报表无法加载。
解决方案
方案1:组件B添加条件渲染
只有当reportId和embedUrl都不为空时,才渲染<PowerBIEmbed>组件,避免无效配置传入。
修改后的组件B代码:
import React from "react"; import { PowerBIEmbed } from "powerbi-client-react"; import { models } from "powerbi-client"; const componentB = (props) => { const { reportId, embedUrl } = props; // 只有当reportId和embedUrl都有效时才渲染组件 if (!reportId || !embedUrl) { return <div>加载报表中...</div>; // 可替换为自定义加载状态 } return ( <div> <PowerBIEmbed embedConfig={{ type: "report", id: reportId, embedUrl: embedUrl, accessToken: "long string of power bi access token", tokenType: models.TokenType.Aad, settings: { panes: { filters: { expanded: false, visible: false, }, }, background: models.BackgroundType.Transparent, }, }} eventHandlers={ new Map([ ["loaded", () => console.log("Report loaded")], ["rendered", () => console.log("Report id: ", reportId)], ["error", (event) => console.log(event.detail)], ["visualClicked", () => console.log("visual clicked")], ["pageChanged", (event) => console.log(event)], ]) } cssClassName={"reportClass"} getEmbeddedComponent={(embeddedReport) => { window.report = embeddedReport; }} /> </div> ); }; export default componentB;
方案2:修复组件A的潜在问题
组件A中存在几处小问题,修正后确保数据正确获取:
- 重复调用
useLocation(),合并为一次调用; - 变量
url未声明,添加const关键字; details初始值改为空对象(接口返回单个客户详情,而非数组);- 模板字符串拼接URL更简洁;
- 修复导入组件的语法错误;
修改后的组件A代码:
import React, { useEffect, useState } from "react"; import { useLocation } from "react-router-dom"; import axios from "axios"; import componentB from "./componentB"; const componentA = () => { const location = useLocation(); const { id: Id, data: Value, customerId } = location.state; const [details, setDetails] = useState({}); const [reportId, setReportId] = useState(""); const [embedUrl, setEmbedUrl] = useState(""); useEffect(() => { const fetchData = async () => { try { const response = await axios.get(`http://localhost:8080/Api/GetData/${customerId}`); const data = response.data; setDetails(data); const url = new URL(data.visualizationUrl); const queryParam = new URLSearchParams(url.search); setReportId(queryParam.get("reportId")); setEmbedUrl(url.href); } catch (e) { console.log("error", e); } }; fetchData(); }, [customerId]); return ( <> <div> <p>{details.customerName}</p> <p>{details.customerAddress}</p> </div> <div> <componentB reportId={reportId} embedUrl={embedUrl} /> </div> </> ); }; export default componentA;
内容的提问来源于stack exchange,提问作者adventureworks
相关产品推荐
相关产品推荐

