我正在使用带有useEffect的redux thunk从API提取数据。但是,我最终遇到了从API提取数据的无限循环。我将空数组用作useEffect中的第二个参数,但它仍可无限次获取数据。但是我可以解决这个问题。这是我的代码:
这是AcademicYearList.js
import React, { useEffect, useCallback } from 'react';
import cx from 'classnames';
import { makeStyles } from '@material-ui/core/styles';
import Academic from '@material-ui/icons/CalendarToday';
import Edit from '@material-ui/icons/Edit';
import Delete from '@material-ui/icons/Delete';
import IconButton from '@material-ui/core/IconButton';
import Tooltip from '@material-ui/core/Tooltip';
import { Link } from 'react-router-dom';
import GridContainer from 'components/theme/Grid/GridContainer';
import GridItem from 'components/theme/Grid/GridItem';
import Card from 'components/theme/Card/Card';
import CardBody from 'components/theme/Card/CardBody';
import CardIcon from 'components/theme/Card/CardIcon';
import CardHeader from 'components/theme/Card/CardHeader';
import ThemeButton from 'components/theme/CustomButtons/Button';
import Table from 'components/common/Table/Table';
import LoadablePaper from 'components/common/Paper/LoadablePaper';
import LoadablePaperContent from 'components/common/Paper/LoadablePaperContent';
import { useSelector, useDispatch } from 'react-redux';
import { getTranslate } from 'react-localize-redux';
import * as ROUTES from 'variables/routeNames';
import { getAcademicYears } from 'redux/actions/academicYear';
import settings from 'settings';
import styles from 'assets/sts/jss/views/academicYear/academicYearStyle';
import * as moment from 'moment';
const useStyles = makeStyles(styles);
const AcademicYear = (props) => {
const classes = useStyles();
const dispatch = useDispatch();
const localize = useSelector((state) => state.localize);
const isLoading = useSelector(state => state.academicYear.isLoadingGet);
const academicYears = useSelector(state => state.academicYear.academicYears);
const translate = getTranslate(localize);
const fetchData = useCallback(
() => dispatch(getAcademicYears()),
[dispatch]
);
useEffect(() => {
if (academicYears.length === 0 && !isLoading) {
fetchData();
}
}, []);
return (
<LoadablePaper
rendered
loading={isLoading}
>
<LoadablePaperContent>
<GridContainer>
<GridItem xs={12}>
<Card>
<CardHeader color="gold" icon>
<CardIcon color="gold">
<Academic />
</CardIcon>
<h4 className={classes.cardIconTitle}>{translate('academicYear.title')}</h4>
</CardHeader>
<CardBody>
<Table
size='small'
tableHead={[
{ id: 'start_year', isNeedSort: false, label: translate('academicYear.year') },
{ id: 'start_date', isNeedSort: false, label: translate('academicYear.start') },
{ id: 'end_date', isNeedSort: false, label: translate('academicYear.finish') },
{ id: 'short_vacation', isNeedSort: false, label: translate('academicYear.vacation.short') },
{ id: 'long_vacation', isNeedSort: false, label: translate('academicYear.vacation.long') },
{ id: 'action', isNeedSort: false, label: '' }
]}
tableData={
academicYears.map(academic => {
const start_date = moment(academic.start_date, settings.dateFormat);
const end_date = moment(academic.end_date, settings.dateFormat);
const studyYear = `${start_date.year()}-${end_date.year()}`;
const editButton = (
<Tooltip
title={translate('common.button.edit')}
key={translate('common.button.edit')}
>
<IconButton
color='primary'
aria-label='edit'
className={classes.tableIconButton}
component={Link}
to={`${ROUTES.ACADEMIC_YEAR_EDIT_ROOT}/${academic.id}`}
>
<Edit className={classes.icon} />
</IconButton>
</Tooltip>
);
const deleteButton = (
<Tooltip
title={translate('common.button.delete')}
key={translate('common.button.delete')}
>
<IconButton
color='secondary'
aria-label='delete'
className={classes.tableIconButton}
onClick={() => {console.log('delete')}}
>
<Delete className={classes.icon} />
</IconButton>
</Tooltip>
);
return [
studyYear,
academic.start_date,
academic.end_date,
academic.short_vacation ? `${academic.short_vacation.start_date}-${academic.short_vacation.end_date}` : '',
academic.long_vacation ? `${academic.long_vacation.start_date}-${academic.long_vacation.end_date}` : '',
[editButton, deleteButton]
];
})}
customCellClasses={['center', 'center', 'center']}
customClassesForCells={[3, 4, 5]}
customHeadCellClasses={['center', 'center', 'center']}
customHeadClassesForCells={[3, 4, 5]}
count={20}
limit={10}
page={0}
/>
</CardBody>
</Card>
<Link to={ROUTES.ACADEMIC_YEAR_NEW}>
<ThemeButton
color="primary"
className={classes.allButton}
>
{translate('common.button.new')}
</ThemeButton>
</Link>
</GridItem>
</GridContainer>
</LoadablePaperContent>
</LoadablePaper>
);
};
export default AcademicYear;
这是我的动作:
export const getAcademicYears = () => {
return (dispatch) => {
dispatch(getAcademicRequested());
axios.get('/get-academic-years')
.then(
res => {
dispatch(getAcademicSuccess(res.data.data));
}
)
.catch(e => {
dispatch(getAcademicFail(e));
dispatch(showErrorNotification(e.message));
});
};
};