我正在尝试从开放数据中提取数据来制作快速热图。在此过程中,我想添加一些统计数据。几乎一切都运行良好,因为我有数据并且能够渲染 map ,但我不确定一旦获得数据如何处理计算,因为数据输入需要时间。我如何设置以便如果状态变量尚未收到数据,我可以在状态变量上运行函数吗?目前,我得到一个 null 作为作为 props 传递给 StatCard 的数字。
以下是我的尝试:
App.js
import React, { Component } from 'react';
import Leaf from './Leaf';
import Dates from './Dates';
import StatCard from './StatCard';
import classes from './app.module.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
data:[],
cleanData:[],
dateInput: '2019-10-01',
loading: false,
totalInspections: null,
calculate: false
};
}
componentDidMount() {
try {
this.fetchData();
} catch (err) {
console.log(err);
this.setState({
loading: false
})
}
}
fetchData=()=>{
const requestData = async () => {
await fetch(`https://data.cityofnewyork.us/resource/p937-wjvj.json?$where=latitude > 39 AND latitude< 45 AND inspection_date >= '${this.state.dateInput}'&$limit=50000`)
.then(res => res.json())
.then(res =>
//console.log(res)
this.setState({ data: res, loading: true})
)
}
const calculateInspections = () => {
this.setState({totalInspections: this.state.data.length})
}
//call the function
requestData();
if(this.state.data) {
calculateInspections();
}
}
handleDateInput = (e) => {
console.log(e.target.value);
this.setState({dateInput:e.target.value, loading: false}) //update state with the new date value
this.updateData();
//this.processGraph(e.target.value)
}
updateData =() => {
this.fetchData();
}
LoadingMessage=()=> {
return (
<div className={classes.splash_screen}>
<div className={classes.loader}></div>
</div>
);
}
//inspection_date >= '${this.state.dateInput}'&
// https://data.cityofnewyork.us/resource/p937-wjvj.json?$where=inspection_date >= '2019-10-10T12:00:00'
render() {
return (
<div>
<div>{!this.state.loading ?
this.LoadingMessage() :
<div></div>}
</div>
{this.state.totalInspections && <StatCard totalInspections={this.state.totalInspections} /> }
<Dates handleDateInput={this.handleDateInput}/>
<Leaf data={this.state.data} />
</div>
);
}
}
export default App;
StatCard.js
import React from 'react';
const StatCard = ( props ) => {
return (
<div >
{ `Total Inspections: ${props.totalInspections}`}
</div>
)
};
export default StatCard;
尝试修复
componentDidMount() {
try {
this.fetchData();
} catch (err) {
console.log(err);
this.setState({
loading: false
})
}
}
componentDidUpdate () {
if(this.state.data) {
this.setState({totalInspections: this.state.data.length})
}
}
fetchData= async ()=>{
const requestData = () => {
fetch(`https://data.cityofnewyork.us/resource/p937-wjvj.json?$where=latitude > 39 AND latitude< 45 AND inspection_date >= '${this.state.dateInput}'&$limit=50000`)
.then(res => res.json())
.then(res =>
//console.log(res)
this.setState({ data: res, loading: true})
)
}
//call the function
await requestData();
}
请您参考如下方法:
所以你的问题是在任何异步调用之前需要同步设置isLoading状态。
所以在你的componentDidMount中:
componentDidMount() {
try {
this.setState({ loading: true }); // YOU NEED TO SET TRUE HERE
this.fetchData();
} catch (err) {
console.log(err);
this.setState({
loading: false
})
}
}
这可确保您一调用电话即可加载。 然后进行调用,该部分是异步。 一旦数据通过,加载就完成了:
.then(data => {
this.setState({
data: data,
loading: false, // THIS NEEDS TO BE FALSE
totalInspections: this.state.data.length
})
})
此外,您的 render 方法可以有多个 return 语句。返回您的加载布局,而不是使用条件 JSX:
render() {
if (this.state.loading) {
return <div> I am loading </div>
}
return <div> Proper Content </div>;
}






