[英]Wait for API data before render react hooks
我打了兩個 API 電話。 來自getAllCampaign
api 的數據呈現,但對於loadStats
似乎 React 繼續構建一個沒有數據的表,因此拋出 Uncaught TypeError 錯誤:無法讀取未定義的屬性“數據”這就是我正在做的。
coreapihelpers:
export const getAllCampaign = () => {
return fetch(`https://api.truepush.com/api/v1/listCampaign/1`, {
method: "GET",
headers: {
Authorization: `$TOKEN`,
"Content-Type": "application/json",
},
})
.then(response => {
return response.json()
})
.catch(err => console.log(err))
}
export const loadStats = async () => {
const ids = await getAllCampaign()
const data = Promise.all(
ids.data.map(async (i) => await (await fetch(`https://api.truepush.com/api/v1/campaignStats/${i.campaignId}`, {
method: "GET",
headers: {
Authorization: ``$TOKEN``,
"Content-Type": "application/json"
}
})).json())
)
return data
};
allData
output 在控制台上延遲
完整代碼:
import React, {useState, useEffect} from 'react';
import {getAllCampaign, loadStats} from "../helpers/coreapihelpers";
const TableRow = () => {
const [campaigns, setCampaigns] = useState([]);
const [stats, setStats] = useState([]);
const loadAllCampaigns = () => {
getAllCampaign()
.then(data => { setCampaigns(data.data) })
.catch(err => { console.log(err) });
};
const loadAllStats = () => {
loadStats()
.then(data => { setStats(data) })
.catch(err => { console.log(err) });
}
useEffect(() => {
loadAllCampaigns();
loadAllStats();
}, [])
const allData = campaigns.map ? campaigns.map((campaign, i) => ({
...campaign,
...stats[i],
}))
: <h1>API LIMIT EXCEEDS</h1>
return (
<div className="container">
<div className="row">
<div className="col-xs-12">
{allData.map ? allData.map((campaigns, index) => (
<div className="table-responsive" data-pattern="priority-columns">
<table className="table table-bordered table-hover">
<thead>
<tr>
<th>Sr. No</th>
<th>Campaign Id</th>
<th>Campaign Name</th>
<th>Campaign Status</th>
<th>Reach</th>
<th>Sent</th>
<th>Delivered</th>
<th>Views</th>
<th>Clicks</th>
<th>Unsubscribers</th>
</tr>
</thead>
<tbody>
<tr key={index}>
<td>{index + 1}</td>
<td>{campaigns.campaignId}</td>
<td>{campaigns.campaignTitle}</td>
<td>{campaigns.campaignStatus}</td>
<td>{campaigns.data.Reach}</td>
<td>{campaigns.data.Sent}</td>
<td>{campaigns.data.Delivered}</td>
<td>{campaigns.data.Views}</td>
<td>{campaigns.data.Clicks}</td>
<td>{campaigns.data.Unsubscribers}</td>
</tr>
</tbody>
</table>
</div>)) : <h1>API Limit Exceeds / API Token Broken</h1>}
</div>
</div>
</div>
);
}
export default TableRow;
我認為問題在於您應該檢查是否已填充 state campaigns
,而不是allData
。 allData
是一個變量,而不是實際的 state。 實際的 state 應該用於條件渲染。 嘗試這個:
替換這個:
allData.map ? allData.map((campaigns, index)
有了這個:
campaigns ? allData.map((campaigns, index)
但是,您應該為 state 創建一個 object,其中包含活動和統計信息,因為您打算將它們用作相應的項目。 或者,您的數據庫查詢應該將它們作為一個項目返回,並有一段時間的加入。
試試這個作為客戶端解決方案:
const [stateObj, setObj] = useState([]);
const campaigns = [];
const stats = [];
const loadAllState = async () => {
try {
campaigns = await getAllCampaign();
} catch (err) {
console.log(err)
}
try {
stats = await loadStats();
} catch (err) {
console.log(err)
}
setObj(campaigns.map((campaign, i) => ({
...campaign,
...stats[i],
})))
};
useEffect(() => {
loadAllState();
}, [])
然后:
stateObj ? stateObj.map((campaigns, index)
您應該查看 allData 是否已這樣定義
{allData ? allData.map((campaigns, index) => .......}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.