我正在尝试从Google Analytics(分析)报告API中提取一些数据,并将数据显示在顶点图表库中。我成功地做到了这一点。但是,我现在想要过滤选项,以便用户在日期范围选择器反应包装器中选择某个日期时,将从API更新顶点图表数据。
我正在努力弄清楚如何更新我的数据,以便在生命周期方法中使用新状态更新状态?我想我正在做些次要的事情,我只是不知道那是什么。我查阅了有关生命周期方法的文档,并说要确保将其包装在我做过的条件内。但是,当满足else条件时,它将导致无限渲染。
这是我的代码:(我卡住的错误是componentWillUpdate生命周期方法),其他所有东西都可以正常工作。
import React from "react";
import Header from "../common/Header";
import Footer from "../common/Footer";
import moment from "moment";
import $ from "jquery";
import ApexCharts from "apexcharts";
import Chart from "react-apexcharts";
import DateRangePicker from "react-bootstrap-daterangepicker";
const VIEW_ID = "";
class Charts extends React.Component {
constructor(props) {
super(props);
this.printResults = this.printResults.bind(this);
this.pageViews = this.pageViews.bind(this);
this.handleError = this.handleError.bind(this);
this.state = {
loading: true,
filterstartDate: "",
filterendDate: "",
// Start Series Bar State
ChartOne: {
chart: {
id: "ChartOne"
},
colors: ["#e31d1a"],
xaxis: {
categories: [],
labels: {
style: {
colors: []
}
},
title: {
text: "Locations"
}
},
yaxis: {
labels: {
style: {
colors: []
}
},
title: {
text: "Count"
}
}
},
ChartOneSeries: [],
}
pageViews = async () => {
window.gapi.client
.request({
path: "/v4/reports:batchGet",
root: "https://analyticsreporting.googleapis.com",
method: "POST",
body: {
reportRequests: [
{
viewId: VIEW_ID,
dateRanges: [
{
startDate: "7daysAgo",
endDate: "today"
}
],
metrics: [
{
expression: "ga:pageviews"
}
],
dimensions: [
{
name: "ga:country"
}
],
orderBys: [{ fieldName: "ga:pageviews", sortOrder: "DESCENDING" }]
}
]
}
})
.then(this.printResults, this.handleError);
};
componentDidMount() {
$.getScript("https://apis.google.com/js/client:platform.js").done(() => {
window.gapi.signin2.render("my-signin2", {
scope: "profile email",
width: 240,
height: 50,
longtitle: true,
theme: "dark",
onsuccess: this.pageViews,
onfailure: this.handleError
});
});
}
//log the data
printResults(response) {
let pageviewLocation = [];
let pageviewCount = [];
let pageviewTotal = response.result.reports[0].data.totals[0].values[0];
let totalComma = pageviewTotal
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
response.result.reports[0].data.rows.map(value => {
//console.log(value.dimensions);
pageviewLocation.push(value.dimensions[0]);
pageviewCount.push(parseInt(value.metrics[0].values[0]));
});
//console.log(total);
this.setState({
loading: false,
ChartOne: {
title: {
text: totalComma,
align: "center",
style: {
fontSize: "20px"
}
},
subtitle: {
text: "Total Page Views",
align: "center",
style: {
fontSize: "14px",
cssClass: "apexcharts-yaxis-title"
}
},
plotOptions: {},
...this.state.ChartOne,
xaxis: {
width: 1,
...this.state.ChartOne.xaxis,
labels: {
show: false,
...this.state.ChartOne.xaxis.labels,
style: {
...this.state.ChartOne.xaxis.labels.style
}
},
categories: pageviewLocation
},
yaxis: {
min: 0,
...this.state.ChartOne.yaxis,
labels: {
//show: false,
...this.state.ChartOne.yaxis.labels,
style: {
...this.state.ChartOne.yaxis.labels.style
}
}
}
},
ChartOneSeries: [
{
name: "Total Page Views",
data: pageviewCount
}
]
});
}
componentDidUpdate(prevProps, prevState) {
if (this.state.filterstartDate === "" && this.state.filterendDate === "") {
console.log("they are empty");
} else {
this.setState({
// this fails immediately once the condition is met
test: "success!"
});
}
}
Datepicker = async (event, picker) => {
this.setState({
filterstartDate: moment(picker.startDate._d).format("YYYY-MM-DD"),
filterendDate: moment(picker.endDate._d).format("YYYY-MM-DD")
});
//console.log(this.state);
};
//or the error if there is one
handleError(reason) {
console.error(reason);
console.error(reason.result.error.message);
}
render() {
//console.log();
return (
<div className="containerfluid" id="fullWidth">
<Header />
<div className="container" id="chartContainer">
<h1>Site Analytics</h1>
<div className="row">
<div className="col-md-12">
<DateRangePicker
startDate={moment().format("MM-DD-YYYY")}
endDate={moment().format("MM-DD-YYYY")}
onApply={this.Datepicker}
>
<button className="btn btn-info">
<i className="fas fa-filter">
<span
style={{
fontFamily: "Roboto, san-serif",
fontWeight: "normal",
padding: "5px"
}}
>
Filter Date
</span>
</i>
</button>
</DateRangePicker>
</div>
</div>
<div className="row">
<div className="col-md-4">
{/* Chart One Line */}
{this.state.loading ? (
<React.Fragment>
<i className="fas fa-spinner fa-3x" id="loader" /> Please wait
...!
</React.Fragment>
) : (
<div className="chartContainer">
<Chart
options={this.state.ChartOne}
series={this.state.ChartOneSeries}
type="line"
width={400}
height={300}
/>
</div>
)}
</div>
</div>
<div id="my-signin2" />
</div>
<Footer />
</div>
);
}
}
export default Charts;
答案 0 :(得分:4)
使用setState
时,将再次触发生命周期。如果您未将filterstartDate
和filterendDate
设置为""
,则将继续无限调用setState。
componentDidUpdate(prevProps, prevState) {
if (this.state.filterstartDate === "" && this.state.filterendDate === "") {
console.log("they are empty");
} else {
this.setState({
filterstartDate: "",
filterendDate: "",
test: "success!"
});
}
}