我有一个包含多个接口的项目,在这些接口中有一个用于在Dashboard中显示统计数据的接口。
但是我遇到了一个问题,就是死循环,死循环的原因是什么,怎么解决?
此文件显示 Jmeter 板,并包含BarChart
调用。
这个错误在我看来:
Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
BarChart.tsx
:
import { Row, Col, Card } from "antd";
import { FunctionComponent, useEffect, useState } from "react";
import Chart from "react-google-charts";
import { FormattedMessage } from "react-intl";
import { useQuery } from "react-query";
import statisticCharts from '../../../../api/nuclearMedicineApi/services/Statistic';
import { options_3 } from "../chartsOptions";
interface BarChartsProps { }
interface ValueDto {
x: any,
yMale: any,
yFemale: any
}
const BarCharts: FunctionComponent<BarChartsProps> = () => {
var today = new Date();
var year = today.getFullYear();
const chartsQueryTopographyData = useQuery(['chartsQueryTopographyData'], () =>
statisticCharts.GetTopographyStatistic({ FilterType: 1, StartDate: `${year}-01-01`, EndDate: `${year}-12-31` }),
);
const chartsQueryAgeData = useQuery(['chartsQueryAgeData'], () =>
statisticCharts.GetTopographyStatistic({ FilterType: 3, StartDate: `${year}-01-01`, EndDate: `${year}-12-31` }),
);
var xytTopography: any[] = [['topography', 'ذكر', 'أنثى']];
var topography: any[] = [['topography', 'المرضى المصابين']];
var ageBar: any[] = [['age', 'المرضى المصابين']];
const [xytotalTopography, setxytotalTopography] = useState<any[]>([])
const [xtopography, setXTopography] = useState<any[]>([]);
const [xyAge, setxyAge] = useState<any[]>([])
useEffect(() => {
// x = topography, y= male, y1= female
chartsQueryTopographyData?.data?.map((xy: any, index: any) => {
if (xy?.x !== undefined && xy?.yMale !== undefined && xy?.yFemale !== undefined) {
let x1: any = xy.x;
let y: any = xy.yMale;
let y1: any = xy.yFemale;
let xyData: any[] = [x1, y, y1];
xytTopography.push(xyData);
setxytotalTopography(xytTopography)
return xytTopography;
}
})
// x=topography, y=yTotal
chartsQueryTopographyData?.data?.map((xy: any, index: any) => {
if (xy?.x !== undefined && xy?.yTotal !== undefined) {
let x1: any = xy.x;
let y: any = xy.yTotal;
let xyData: any[] = [x1, y]
topography.push(xyData);
setXTopography(topography)
return topography;
}
})
// x= age y= yTotal
chartsQueryAgeData?.data?.map((xy: any, index: any) => {
if (xy?.x !== undefined && xy?.yTotal !== undefined) {
let x1: any = xy.x;
let y: any = xy.yTotal;
let xyData: any[] = [x1, y]
ageBar.push(xyData);
setxyAge(ageBar)
return ageBar;
}
})
}, [chartsQueryTopographyData, chartsQueryAgeData]);
return (<>
{/* bar chart topography with male and female */}
<Row>
<Col className='mt-4' lg={24}>
<Card className='card-chart card-bar-chart'>
<Row>
<Col lg={19}>
<h3>
<FormattedMessage id='number-of-cancer-cases-by-male-female' />{' '}
{year}{' '}
</h3>
</Col>
</Row>
<Row className='mt-8'>
<Col lg={24}>
<Chart
chartType="BarChart"
width="100%"
height="400px"
data={xytotalTopography}
options={options_3}
/>
</Col>
</Row>
</Card>
</Col>
</Row>
<Row>
{/* bar chart x=topography with y=yTotal*/}
<Col className='mt-4' lg={24}>
<Card className='card-chart card-bar-number-chart'>
<Row>
<Col lg={19}>
<h3>
{' '}
<FormattedMessage id='number-of-cancer-cases-by-number' />{' '}
{year}{' '}
</h3>
</Col>
</Row>
<Row className='mt-8'>
<Col lg={24}>
<Chart
chartType="BarChart"
width="100%"
height="400px"
data={xtopography}
options={options_3}
/>
</Col>
</Row>
</Card>
</Col>
</Row>
<Row>
{/* bar chart x=topography with y=Age*/}
<Col className='mt-4' lg={24}>
<Card className='card-chart card-bar-age-chart'>
<Row>
<Col lg={19}>
<h3>
{' '}
<FormattedMessage id='number-of-cancer-cases-by-age' />{' '}
{year}{' '}
</h3>
</Col>
</Row>
<Row className='mt-8'>
<Col lg={24}>
<Chart
chartType="BarChart"
width="100%"
height="400px"
data={xyAge}
options={options_3}
/>
</Col>
</Row>
</Card>
</Col>
</Row>
</>)
}
export default BarCharts;
该文件显示BarChart
,并在内部调用条形图的API:DashboardChart.tsx
:
import { Card, Col, Row, Spin } from 'antd';
import { FunctionComponent, useContext, useEffect, useState } from 'react';
import '../../../styles/dashboard/index.scss';
import { AuthContext, IAuthContext } from '../../../contexts/auth-context';
import colors from '../../../constants/colors';
import calendar1 from '../../../assets/icons/calendar1-icon.svg';
import waving from '../../../assets/icons/waving-hand-icon.svg';
import { FormattedMessage } from 'react-intl';
import ClosestFreeAppointment from './charts/closestFreeAppointment';
import BarCharts from './charts/barCharts';
import PieCharts from './charts/pieCharts';
interface DashboardProps { }
const Dashboard: FunctionComponent<DashboardProps> = () => {
const current = new Date();
const date = `${current.getFullYear()}/${current.getMonth() + 1
}/${current.getDate()}`;
const auth = useContext<IAuthContext>(AuthContext);
return (
<>
<div className='dashdoard-donutData'>
{/* welcome */}
<Row>
<Card className='card-welcome'>
<Row className='center'>
<Col lg={20}>
<Row>
<Col>
<FormattedMessage id='welcome' />
{' '}
{auth.userData?.fullName} !
</Col>
<Col className='mr-2 ml-2'>
<img src={waving} alt='waving' />
</Col>
<Col>
<small>
<FormattedMessage id='follow' />
</small>
</Col>
</Row>
</Col>
<Col lg={4}>
<Row
style={{
color: colors.primaryColor,
}}
justify='end'
>
<Col>
<img
src={calendar1}
alt='calendar1'
/>
</Col>
<Col>
{' '}
{'\u00a0\u00a0'}{' '}
<FormattedMessage id='today' />
{date}
</Col>
</Row>
</Col>
</Row>
</Card>
</Row>
{/* Close Date Appointment*/}
<ClosestFreeAppointment />
{/* Bar Charts */}
<BarCharts />
{/* Pie Charts */}
<PieCharts />
</div>
</>
);
};
export default Dashboard;
2条答案
按热度按时间vaj7vani1#
问题是,在每次重新渲染时,
useQuery
将返回一个带有新引用的新对象,并且该对象被包含在useEffect
的dependencies数组中,从而使其再次触发,设置其中的其他状态,触发另一次重新渲染,等等......因为你只是使用
useEffect
钩子来根据useQuery
返回的对象的data
属性设置一些状态,所以你有几个选项。其中一个(不推荐,参考this article)是在数据可用时使用useQuery
的onSuccess
选项来设置这些状态:理想的解决方案是从这三个状态中进行处理(
xytotalTopography
,xtopography
,xyAge
)并在渲染期间计算这些值。(从您的代码来看,它们似乎是常量,并且没有包含在queryKey
数组中)。看起来你现在使用的是react-query v3。顺便说一句,react-query目前的稳定版本是v4,v5即将发布。我建议你更新一下。
ercv8c1e2#
我认为你在错误的地方设置了状态,请尝试在Map之外进行。我还建议将
map
更改为forEach
。还可以考虑只运行一次chartsQueryTopographyData循环。注意:我不知道这是否是原因,因为你没有提供一个工作的例子.但你可以试试这个: