簡體   English   中英

在渲染反應鈎子之前等待 API 數據

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM