简体   繁体   English

React hooks async useEffect 加载数据库数据

[英]React hooks async useEffect to load database data

I'm using async useEffect in React because I need to do database requests.我在 React 中使用异步 useEffect 因为我需要执行数据库请求。 Then, add this data to my react-charts-2然后,将此数据添加到我的react-charts-2

const [ plSnapShot, setPlSnapShot ] = useState({
   grossIncome: 0.00,
   opeExpenses: 0.00,
   nonOpeExpenses: 0.00,
   netIncome: 0.00,
   grossPotencialRent: 0.00,
   lastMonthIncome: 0.00
});

const [ thisMonthPayment, setThisMonthPayments ] = useState({
    labels: [],
    data: [],
    color: 'blue'
});


useEffect(() => {
    async function fetchData() {
        await axios.get(`${url.REQ_URL}/home/getUserFullName/${userID}`)
            .then(async (res) => {
                setUserFullName(res.data);

                await axios.get(`${url.REQ_URL}/home/getThisMonthPayments/${propertyID}`)
                    .then(async (resMonthPay) => {
                        let total = 0;
                        let obj = {
                            labels: [],
                            data: [],
                            color: 'blue'
                        };
                        const data = resMonthPay.data;
                        for(const d of data) {
                            obj.labels.push(helper.formatDate(new Date(d.date)));    
                            obj.data.push(d.amount);
                            total += d.amount;
                        }
                        setThisMonthPayments(obj);
                        setTotalEarnedMonth(parseFloat(total));

                        await axios.get(`${url.REQ_URL}/home/plSnapshot/${propertyID}`)
                            .then(async (resPL) => {
                                const data = resPL.data;
                                setPlSnapShot({
                                    grossIncome: parseFloat(data.GrossIncome || 0).toFixed(2),
                                    opeExpenses: parseFloat(data.OperatingExpenses || 0).toFixed(2),
                                    nonOpeExpenses: parseFloat(data.NonOperatingExpenses || 0).toFixed(2),
                                    netIncome: parseFloat(data.NetIncome || 0).toFixed(2),
                                    grossPotencialRent: parseFloat(data.GrossPotencialRent || 0).toFixed(2),
                                    lastMonthIncome: parseFloat(data.LastMonthIncome || 0).toFixed(2)
                                });
                            });
                    });
            });
    }
    fetchData();
}, [propertyID, userID]);

const pieChart = {
    chartData: {
        labels: ['Gross Income', 'Operating Expenses', 'Non Operating Expenses'],
        datasets: [{
            data: [plSnapShot.grossIncome, plSnapShot.opeExpenses, plSnapShot.nonOpeExpenses],
            backgroundColor: [
                ChartConfig.color.primary,
                ChartConfig.color.warning,
                ChartConfig.color.info
            ],
            hoverBackgroundColor: [
                ChartConfig.color.primary,
                ChartConfig.color.warning,
                ChartConfig.color.info
            ]
        }]
    }
};

const horizontalChart = {
    label: 'Last Month Income',
    labels: ['Gross Potencial Rent', 'Last Month Income'],
    chartdata: [plSnapShot.grossPotencialRent, plSnapShot.lastMonthIncome]
};

Here is an example of how I call the Chart component in my code in the render/return method.这是我如何在渲染/返回方法的代码中调用 Chart 组件的示例。

<TinyPieChart
   labels={pieChart.chartData.labels}
   datasets={pieChart.chartData.datasets}
   height={110}
   width={100}
/>

And my Pie Chart component is just to display it而我的饼图组件只是为了显示它

import React from 'react';
import { Pie } from 'react-chartjs-2';

// chart congig
import ChartConfig from '../../Constants/chart-config';

const options = {
    legend: {
        display: false,
        labels: {
            fontColor: ChartConfig.legendFontColor
        }
    }
};

const TinyPieChart = ({ labels, datasets, width, height }) => {
    const data = {
        labels,
        datasets
    };
    return (
        <Pie height={height} width={width} data={data} options={options} />
    );
}

export default TinyPieChart;

Mostly of the times it works just fine, but sometimes the chart data is loaded and displayed in the screen real quick, then it disappear and the chart is displayed empty (no data).大多数情况下它工作得很好,但有时图表数据会很快加载并显示在屏幕上,然后它消失并且图表显示为空(无数据)。 Am I loading it properly with the useEffect or should I use another method?我是使用 useEffect 正确加载它还是应该使用其他方法?

Thanks you.谢谢。

The momentary flashing is likely due to the fact that the chart data is empty on first render.瞬间闪烁可能是由于图表数据在第一次渲染时为空。 So depending on the time it take for your useEffect to fetch the data, that flashing may present a real problem.因此,根据您的useEffect获取数据所需的时间,闪烁可能会带来真正的问题。

One common solution is to use a state variable to indicate that the data is being loaded and either not display anything in place of the chart or display a loaded of some sort.一种常见的解决方案是使用 state 变量来指示正在加载数据,并且要么不显示任何内容来代替图表,要么显示某种加载。 So you can add something like you suggested in the comments const [ loader, setLoader ] = useState(true) .因此,您可以添加您在评论const [ loader, setLoader ] = useState(true)中建议的内容。 Then once the data is loaded, togged it to false .然后一旦加载数据,将其切换为false

Meanwhile, inside your render function, you would do:同时,在您的渲染 function 中,您将执行以下操作:

...
...
{loader ? 
   <div>Loading....</div>
 :
   <TinyPieChart
    labels={pieChart.chartData.labels}
    datasets={pieChart.chartData.datasets}
    height={110}
    width={100}
   />

}

loader can go from true to false or vise versa, depending on what make more intuitive sense to you. loader可以 go 从真到假或反之亦然,这取决于对您来说更直观的感觉。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM