【问题标题】:Code Execute First Before the data is Fetching in react js在react js中获取数据之前首先执行代码
【发布时间】:2022-10-14 22:26:29
【问题描述】:

我有一个条件,我从 API 获取数据需要 8 秒才能在第一次使用效果和第二次使用效果中做出响应,我想使用该数据,但问题是代码在数据获取之前首先执行,而我没有' t有数据在二次使用效果

import React, { useState, useEffect } from "react";
import { Col, Container, Row } from "react-bootstrap";
import Bluecard from "../../components/bluecard/Bluecard";
import Linechart from "../../charts/linechart/Linechart";
import Solar_1 from "../../assets/images/Solar_1.png";
import Solar_2 from "../../assets/images/Solar_2.png";
import Solar_3 from "../../assets/images/Solar_3.png";
import Solar_4 from "../../assets/images/Solar_4.png";
import Solar_5 from "../../assets/images/Solar_5.png";
import Solar_6 from "../../assets/images/Solar_6.png";
import Solar_7 from "../../assets/images/Solar_7.png";
import Solar_8 from "../../assets/images/Solar_8.png";

function Solarcopy() {
    // ================ First Blue Card Data =======================//
    const [isLoading, setIsLoading] = useState(true);
    const [blueCardData, setBlueCardData] = useState([]);
    const [lineData, setLineData] = useState({
    labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
    datasets: [
        {
        label: "Users Gained",
        data: [10, 20, 30, 10, 15, 30],
        backgroundColor: [
            "rgba(75,192,192,1)",
            "#ecf0f1",
            "#50AF95",
            "#f3ba2f",
            "#2a71d0",
        ],
        borderColor: "black",
        borderWidth: 2,
        fill: true,
        },
    ],
    });
    // useEffect(() => {
    //   const fetchdata = async () => {
    //     const response = await fetch("http://192.168.18.21:8000/performance/solar-overview/")
    //     .then((response)=>{
    //       if (!response.ok) {throw new Error("Error in fetching");} 
    //       else {return response.json;}
    //     })
    //     console.log(response)
    //   };
    // }, []);
    useEffect(() => {
    let dataValues = fetch(
        "http://192.168.18.21:8000/performance/solar-overview/"
    )
        .then((dataValues) => dataValues.json())
        .then((dataValues) => {
        // console.log(dataValues)
        setBlueCardData(dataValues);
        setIsLoading(false);
        });
    }, []);
    // ================ First Blue Card Data =======================//

    // ================ First Linechart Data =======================//
    useEffect(() => {
    const arr3 = [];
    const arr4 = [];
    if (!isLoading) {
        blueCardData.pr_hourly.time.map((item) => {
        arr4.push(item.time);
        });
        blueCardData.pr_hourly.pr_hourly.map((item) => {
        arr4.push(item.pr_hourly);
        });
    } else {
        console.log("API Data Loading");
        console.log(arr3);
        setIsLoading(true);
    }

    // fetch("https://jsonplaceholder.typicode.com/users?_limit=5")
    //   .then((response) => response.json())
    //   .then((json) => {
    // arr3 = blueCardData.pr_hourly.time;
    // console.log(arr3)
    // blueCardData.pr_hourly.pr_hourly.map((item) => {
    //   arr4.push(item.pr_hourly);
    // });

    setLineData({
        labels: arr3,
        datasets: [
        {
            label: "Values",
            data: arr4,
            backgroundColor: [
            "rgba(75,192,192,1)",
            "#ecf0f1",
            "#50AF95",
            "#f3ba2f",
            "#2a71d0",
            ],
            borderColor: "black",
            borderWidth: 2,
            fill: true,
        },
        ],
    });
    //   });
    }, []);
    // ================ First Linechart Data =======================//
    // ================== API Response Validation ====================//
    if (isLoading) {
    return <p>Loading Data</p>;
    }
    // ================== API Response Validation ====================//
    return (
    <>
        <section>
        <Container fluid>
            <Row>
            <Col lg={6}>
                <Row>
                <Col xl={6} className="mt-3">
                    <Bluecard
                    heading={blueCardData.today_revenue}
                    spanText={"PKR"}
                    text={"Today's Revenue"}
                    image={Solar_1}
                    />
                </Col>
                <Col xl={6} className="mt-3">
                    <Bluecard
                    heading={blueCardData.cuf}
                    spanText={"%"}
                    text={"CUF"}
                    image={Solar_2}
                    />
                </Col>
                <Col xl={6} className="mt-3">
                    <Bluecard
                    heading={blueCardData.total_yield}
                    spanText={"KWH"}
                    text={"Today's Yield"}
                    image={Solar_3}
                    />
                </Col>
                <Col xl={6} className="mt-3">
                    <Bluecard
                    heading={blueCardData.cuf}
                    spanText={"%"}
                    text={"CUF"}
                    image={Solar_4}
                    />
                </Col>
                <Col xl={6} className="mt-3">
                    <Bluecard
                    heading={blueCardData.system_size}
                    spanText={"kW"}
                    text={"System Size"}
                    image={Solar_5}
                    />
                </Col>
                <Col xl={6} className="mt-3">
                    <Bluecard
                    heading={blueCardData.inverters}
                    spanText={""}
                    text={"Number Of Inverters"}
                    image={Solar_6}
                    />
                </Col>
                <Col xl={6} className="mt-3">
                    <Bluecard
                    heading={blueCardData.performance_ratio}
                    spanText={"%"}
                    text={"Performance Ratio"}
                    image={Solar_7}
                    />
                </Col>
                <Col xl={6} className="mt-3">
                    <Bluecard
                    heading={blueCardData.tc_performance_ratio}
                    spanText={"%"}
                    text={"TCPR"}
                    image={Solar_8}
                    />
                </Col>
                {/* {blueCardData.map((item) => (
                    <Col xl={6} key={item.id}>
                    <Bluecard
                        heading={item.id}
                        spanText={item.albumId}
                        text={item.title}
                        image={item.thumbnailUrl}
                    />
                    </Col>
                ))} */}
                </Row>
            </Col>
            </Row>
        </Container>
        </section>
        <section className="mt-lg-5 mt-5">
        <Container fluid>
            <Row>
            <Col lg={6}>
                <Linechart chartData={lineData} />
            </Col>
            </Row>
        </Container>
        </section>
    </>
    );
}

export default Solarcopy;

【问题讨论】:

  • 请以文本而不是图像的形式提供代码。

标签: reactjs


【解决方案1】:

不要使用具有相同依赖数组 ([]) 的两个 useEffect,因为您的代码无需等待即可执行。 除了将两个 useEffect 的逻辑合二为一之外,您还可以使用 async/await 而不是 promises 语法,这将更具可读性

【讨论】:

  • 我用文本格式编辑了上面的代码,你能用正确的方式写吗?
【解决方案2】:

如果您将 useEffect 与 ([]) 一起使用,它将仅在第一次加载时起作用。如果您想在 isLoading false 时使其第二个 useEffect 起作用,请使用它 ([isLoading]) 在这种情况下,每次 isLoading 更改第二个 useEffect 都会再次起作用。

【讨论】:

    【解决方案3】:

    您对 API 进行 fetch 调用 - 此代码是异步,因此另一个同步代码不会等待它并在获取数据之前继续运行。

    所以你应该做的是将fetch 的所有异步代码放入一个async 函数中,该函数将返回你获取的数据(作为一个promise)。

    重要的:你写的地方:setBlueCardData(dataValues) -状态更新不会立即发生,因此您不会在写入此行后立即将数据存储在状态中。请参阅此link

    相反,我们有一个异步函数,它将为我们返回获取的data,以便我们可以使用它。

    其次,现在你可以只使用一个useEffect,在其中你将调用异步函数,一旦data 被提取并且承诺已解决 - 您将使用它,并完成您需要做的所有映射。

    关于isLoading 状态——您需要做的就是在异步函数的第一行将其设置为true——这意味着现在我们开始获取,然后在函数结束时将其设置为错误的。

    代码:

    异步功能:

    const fetchData = async () => {
        setIsLoading(true); //starting to fetch.
        const response = await fetch('http://192.168.18.21:8000/performance/solar-overview');
        const dataValues = await response.json();
        setBlueCardData(dataValues); //Won't update immediately!
        setIsLoading(false);//finished loading.
        return dataValues;//returning the data.
      };
    

    使用效果:

      useEffect(() => {
        fetchData().then((data) => {
          //This all inside the then() block - which means we finished loading and got the data.
          const arr3 = [];
          const arr4 = [];
          data.pr_hourly.time.map((item) => {
            arr4.push(item.time);
          });
          data.pr_hourly.pr_hourly.map((item) => {
            arr4.push(item.pr_hourly);
          });
          setLineData({ /* .. your code here .. */ });
        });
      }, []);
    

    还有 JSX:(把你自己的 JSX 放在这里)

      if (isLoading) {
        return <p>Loading Data</p>;
      }
      return <div>Your data is here....</div>;
    }
    

    【讨论】:

      猜你喜欢
      • 2018-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多