reactjs - React hooks async useEffect 加载数据库数据
问题描述
我在 React 中使用异步 useEffect 因为我需要执行数据库请求。然后,将此数据添加到我的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]
};
这是我如何在渲染/返回方法的代码中调用 Chart 组件的示例。
<TinyPieChart
labels={pieChart.chartData.labels}
datasets={pieChart.chartData.datasets}
height={110}
width={100}
/>
而我的饼图组件只是为了显示它
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;
大多数情况下它工作得很好,但有时图表数据会很快加载并显示在屏幕上,然后它消失并且图表显示为空(无数据)。我是使用 useEffect 正确加载它还是应该使用其他方法?
谢谢。
解决方案
瞬间闪烁可能是由于图表数据在第一次渲染时为空。因此,根据您useEffect
获取数据所需的时间,闪烁可能会带来真正的问题。
一种常见的解决方案是使用状态变量来指示正在加载数据,并且要么不显示任何内容来代替图表,要么显示某种已加载的数据。因此,您可以添加您在评论中建议的内容const [ loader, setLoader ] = useState(true)
。然后,一旦加载数据,将其切换到false
.
同时,在您的渲染函数中,您将执行以下操作:
...
...
{loader ?
<div>Loading....</div>
:
<TinyPieChart
labels={pieChart.chartData.labels}
datasets={pieChart.chartData.datasets}
height={110}
width={100}
/>
}
loader
可以从真到假,反之亦然,这取决于对您来说更直观的意义。
推荐阅读
- apache-kafka - Kafka Streams QueryableStore - ReadOnlyKeyValueStore 快速访问
- java - 重建回收站视图会导致它消失
- ios - 在 iOS 14 小部件中显示来自 Core Data 的数据的合理方式是什么?
- sql - 使用计算列使用别名的 SQL 连接
- python - 如何以 SaveModel 格式保存具有动态输入形状的 keras 自定义模型?
- java - BDDMockito `given(...).willReturn(...)` 只调用一次模拟,而不是每次调用 `given()` 函数
- node.js - 我可以在 Angular 9 中使用 kafka 消费者/生产者来连接节点服务器吗?
- c# - 如何在浏览器上打开 MS 文档?
- android - Ionic 3 应用程序停止发出网络请求
- python - 如何比较跨平台 pathlib 路径?