如何使用 React 从对象数组中获取数据,通过 API 端点将其传递给 .fetch() 所需的对象值?
How can I fetch data from an array of objects, pass it through an API end point to .fetch() the needed object value using React?
我正在使用 PowerBI 使用 React 创建报告仪表板,需要将嵌入令牌值传递到我们创建的后端端点,然后将该新值传递到 PowerBI 嵌入组件以正确显示报告。
如果我手动放入嵌入令牌值,我可以让应用程序正常工作,但由于多种原因(例如安全性和耗时),这并不理想,所以我试图在 React 应用程序中自动执行此操作.
我们如何手动显示报告是通过 switch 语句,因为有多个报告可供选择,并且每个报告都放置了 PowerbiEmbedded 组件,并从本地 JSON 文件中提取适当的值,其中报告 ID并放置嵌入 URL。这是我为概念的 testing/proof 粘贴标记的同一个文件,并且有一个单独的组件处理获取请求(下面的 RequestToken.js),并且在如何将其与 ReportDashboard.js 连接方面有点迷失因为这是处理每个报告的显示。
如有任何建议和帮助,我们将不胜感激!
RequestToken.js
import React from "react"
import { groupVariables } from '../constants/reportVariables';
// This will handle token retrieval for each
class RequestAccessToken extends React.Component {
state = {
isLading: true,
tokenDetails: [],
error: null
};
getTokenDetails() {
// where we're fetching data from b2b for proof of concept
axios.get(`/api/token/${accessToken}`)
// got the API response and receive data in JSON format
.then(response =>
response.data.results.map(tokenDetail => ({
token: `${tokenDetail.token}`
}))
)
.then(tokenDetails => {
this.setState({
tokenDetails,
isLoading: false
});
})
// catch any errors we hit and update the output
.catch(error => this.setState({ error, isLoading: false }));
}
componentDidMount() {
this.getTokenDetails();
}
render() {
const { isLoading, tokenDetails } = this.state;
return (
<React.Fragment>
{!isLoading ? (
tokenDetails.map(tokenDetail => {
const { token } = tokenDetail
return (
console.log(tokenDetail)
);
})
// If there is a delay in data, let's let the user know it's loading
) : (
<h3>Loading...</h3>
)}
</React.Fragment>
);
}
}
ReportDashboard.js
import React from 'react';
import { reportVariables } from '../constants/reportVariables.js';
import PowerbiEmbedded from 'react-powerbi'
function Reporting({ activeView }) {
// configure the reportIds and report name in constants/reportVariables.js
let reportData;
switch(activeView){
case 'Business to Consumer':
reportData = <div>
<PowerbiEmbedded
id={reportVariables.reportIds.b2c}
embedUrl={reportVariables.reportURL.b2c}
accessToken={reportVariables.reportToken.b2c}
filterPaneEnabled={false}
navContentPaneEnabled={false}
embedType={`report`}
tokenType={`Embed`}
permissions={`All`}
/>
</div>
break;
case 'Business to Business':
reportData = <div>
<PowerbiEmbedded
id={reportVariables.reportIds.b2b}
embedUrl={reportVariables.reportURL.b2b}
accessToken={reportVariables.reportToken.b2b}
filterPaneEnabled={false}
navContentPaneEnabled={false}
embedType={`report`}
tokenType={`embed`}
permissions={`All`}
/>
</div>
break;
case 'Agent':
reportData = <div>
<PowerbiEmbedded
id={reportVariables.reportIds.agent}
embedUrl={reportVariables.reportURL.agent}
accessToken={reportVariables.reportToken.agent}
filterPaneEnabled={false}
navContentPaneEnabled={false}
embedType={`report`}
tokenType={`embed`}
permissions={`All`}
/>
</div>
break;
case 'A/B Testing':
reportData = <div>
<iframe width="560" height="315" src="https://www.youtube.com/embed/lcGoWfXLRpc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
break;
default:
break;
}
return(
<div className='frameDiv'>
<style>{`
.frameDiv{
justify-content: center;
display: flex;
align-items: center;
width: 85vw;
height: calc(100vh - 39px);
background: #ccc;
}
.powerbi-frame {
width: 85vw;
height: calc(100vh - 39px);
}
`}
</style>
{reportData}
</div>
);
}
export default Reporting
RequestAccessToken 需要在某处 呈现,对吗?截至目前,它只是坐在那里。将其导入您的 Dashboard 组件并呈现它,然后您可以在那里访问您的令牌。
您可以通过多种方式将令牌传递给其他组件,但归根结底是 "pass it as a prop." 您可以使用 React 上下文、集中式状态管理或 parent/child 嵌套。我认为最优雅的另一种选择是创建一个高阶组件(HOC),它用 RequestAccessToken
组件包装任何组件:
import { useEffect, useState } from 'React';
function withAccessToken(accessToken) {
return Component => props => {
const [state, setState] = useState({
isLoading: true,
tokenDetails: [],
error: null
});
useEffect(() => {
axios.get(`/api/token/${accessToken}`)
// where we're fetching data from b2b for proof of concept
// got the API response and receive data in JSON format
.then(response =>
response.data.results.map(tokenDetail => ({
token: `${tokenDetail.token}`
}))
)
.then(tokenDetails => {
setState({
tokenDetails,
isLoading: false
});
})
// catch any errors we hit and update the output
.catch(error => setState({ error, isLoading: false }));
}, []);
const { isLoading, tokenDetails, error } = state;
return (
isLoading && <h3>Loading...</h3>
|| error && <h3>Error loading token</h3>
|| <Component {...props} accessToken={tokenDetails}/>
);
};
}
您使用它的方式类似于:
const B2BReport = withAccessToken('some-token-name')(({ accessToken }) =>
<PowerbiEmbedded
id={reportVariables.reportIds.b2b}
embedUrl={reportVariables.reportURL.b2b}
accessToken={accessToken}
filterPaneEnabled={false}
navContentPaneEnabled={false}
embedType={`report`}
tokenType={`embed`}
permissions={`All`}
/>
);
这将创建一个新的 B2BReport
组件,该组件获得由 HOC 注入的 accessToken
prop。然后,您将在 ReportDashboard
组件中呈现此 <B2BReport/>
组件。
我正在使用 PowerBI 使用 React 创建报告仪表板,需要将嵌入令牌值传递到我们创建的后端端点,然后将该新值传递到 PowerBI 嵌入组件以正确显示报告。
如果我手动放入嵌入令牌值,我可以让应用程序正常工作,但由于多种原因(例如安全性和耗时),这并不理想,所以我试图在 React 应用程序中自动执行此操作.
我们如何手动显示报告是通过 switch 语句,因为有多个报告可供选择,并且每个报告都放置了 PowerbiEmbedded 组件,并从本地 JSON 文件中提取适当的值,其中报告 ID并放置嵌入 URL。这是我为概念的 testing/proof 粘贴标记的同一个文件,并且有一个单独的组件处理获取请求(下面的 RequestToken.js),并且在如何将其与 ReportDashboard.js 连接方面有点迷失因为这是处理每个报告的显示。
如有任何建议和帮助,我们将不胜感激!
RequestToken.js
import React from "react"
import { groupVariables } from '../constants/reportVariables';
// This will handle token retrieval for each
class RequestAccessToken extends React.Component {
state = {
isLading: true,
tokenDetails: [],
error: null
};
getTokenDetails() {
// where we're fetching data from b2b for proof of concept
axios.get(`/api/token/${accessToken}`)
// got the API response and receive data in JSON format
.then(response =>
response.data.results.map(tokenDetail => ({
token: `${tokenDetail.token}`
}))
)
.then(tokenDetails => {
this.setState({
tokenDetails,
isLoading: false
});
})
// catch any errors we hit and update the output
.catch(error => this.setState({ error, isLoading: false }));
}
componentDidMount() {
this.getTokenDetails();
}
render() {
const { isLoading, tokenDetails } = this.state;
return (
<React.Fragment>
{!isLoading ? (
tokenDetails.map(tokenDetail => {
const { token } = tokenDetail
return (
console.log(tokenDetail)
);
})
// If there is a delay in data, let's let the user know it's loading
) : (
<h3>Loading...</h3>
)}
</React.Fragment>
);
}
}
ReportDashboard.js
import React from 'react';
import { reportVariables } from '../constants/reportVariables.js';
import PowerbiEmbedded from 'react-powerbi'
function Reporting({ activeView }) {
// configure the reportIds and report name in constants/reportVariables.js
let reportData;
switch(activeView){
case 'Business to Consumer':
reportData = <div>
<PowerbiEmbedded
id={reportVariables.reportIds.b2c}
embedUrl={reportVariables.reportURL.b2c}
accessToken={reportVariables.reportToken.b2c}
filterPaneEnabled={false}
navContentPaneEnabled={false}
embedType={`report`}
tokenType={`Embed`}
permissions={`All`}
/>
</div>
break;
case 'Business to Business':
reportData = <div>
<PowerbiEmbedded
id={reportVariables.reportIds.b2b}
embedUrl={reportVariables.reportURL.b2b}
accessToken={reportVariables.reportToken.b2b}
filterPaneEnabled={false}
navContentPaneEnabled={false}
embedType={`report`}
tokenType={`embed`}
permissions={`All`}
/>
</div>
break;
case 'Agent':
reportData = <div>
<PowerbiEmbedded
id={reportVariables.reportIds.agent}
embedUrl={reportVariables.reportURL.agent}
accessToken={reportVariables.reportToken.agent}
filterPaneEnabled={false}
navContentPaneEnabled={false}
embedType={`report`}
tokenType={`embed`}
permissions={`All`}
/>
</div>
break;
case 'A/B Testing':
reportData = <div>
<iframe width="560" height="315" src="https://www.youtube.com/embed/lcGoWfXLRpc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
break;
default:
break;
}
return(
<div className='frameDiv'>
<style>{`
.frameDiv{
justify-content: center;
display: flex;
align-items: center;
width: 85vw;
height: calc(100vh - 39px);
background: #ccc;
}
.powerbi-frame {
width: 85vw;
height: calc(100vh - 39px);
}
`}
</style>
{reportData}
</div>
);
}
export default Reporting
RequestAccessToken 需要在某处 呈现,对吗?截至目前,它只是坐在那里。将其导入您的 Dashboard 组件并呈现它,然后您可以在那里访问您的令牌。
您可以通过多种方式将令牌传递给其他组件,但归根结底是 "pass it as a prop." 您可以使用 React 上下文、集中式状态管理或 parent/child 嵌套。我认为最优雅的另一种选择是创建一个高阶组件(HOC),它用 RequestAccessToken
组件包装任何组件:
import { useEffect, useState } from 'React';
function withAccessToken(accessToken) {
return Component => props => {
const [state, setState] = useState({
isLoading: true,
tokenDetails: [],
error: null
});
useEffect(() => {
axios.get(`/api/token/${accessToken}`)
// where we're fetching data from b2b for proof of concept
// got the API response and receive data in JSON format
.then(response =>
response.data.results.map(tokenDetail => ({
token: `${tokenDetail.token}`
}))
)
.then(tokenDetails => {
setState({
tokenDetails,
isLoading: false
});
})
// catch any errors we hit and update the output
.catch(error => setState({ error, isLoading: false }));
}, []);
const { isLoading, tokenDetails, error } = state;
return (
isLoading && <h3>Loading...</h3>
|| error && <h3>Error loading token</h3>
|| <Component {...props} accessToken={tokenDetails}/>
);
};
}
您使用它的方式类似于:
const B2BReport = withAccessToken('some-token-name')(({ accessToken }) =>
<PowerbiEmbedded
id={reportVariables.reportIds.b2b}
embedUrl={reportVariables.reportURL.b2b}
accessToken={accessToken}
filterPaneEnabled={false}
navContentPaneEnabled={false}
embedType={`report`}
tokenType={`embed`}
permissions={`All`}
/>
);
这将创建一个新的 B2BReport
组件,该组件获得由 HOC 注入的 accessToken
prop。然后,您将在 ReportDashboard
组件中呈现此 <B2BReport/>
组件。