我正在尝试使用redux,axios和API创建查询页面。在useEffect()
中,如果useSelector
中的变量为空,并且isLoading
的状态为false
,则我执行API请求。但是,即使不对这些变量进行任何更改(已经在依赖项列表中),useEffect
仍会无限期地触发API请求。
在检查状态时,我发现integrationStatusLoading
始终从true
变为false
。看来useEffect
甚至在完成之前的运行之前就被触发了几次。
我的减速器:
import * as spreadsheetActions from './spreadsheetActions';
export const INITIAL_STATE = {
messagesLog: [],
loading: false,
modalIsOpen: false,
integration: {
rows: [],
loading: false
}
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case spreadsheetActions.SET_INTEGRATION_STATUS:
return { ...state, integration: {
...state.integration,
rows: action.payload
}};
case spreadsheetActions.SET_LOADING_INTEGRATION_STATUS:
return { ...state, integration: {
...state.integration,
loading: action.payload
}};
default:
return state;
}
};
jsx:
const IntegrationStatusContainer = function() {
const classes = useStyles();
const dispatch = useDispatch();
const integrationStatusData = useSelector(state => state.spreadsheet.integration.rows);
const integrationStatusLoading = useSelector(state => state.spreadsheet.integration.loading);
useEffect(() => {
if (isEmpty(integrationStatusData) && !integrationStatusLoading) {
dispatch(spreadsheetOperations.getIntegrationStatus());
}
}, [dispatch, integrationStatusData, integrationStatusLoading]);
return (
<IntegrationStatusTable items={integrationStatusData} isLoading={integrationStatusLoading} />
);
};
export default IntegrationStatusContainer;
spreadsheetOperations.js
export const getIntegrationStatus = () => async dispatch => {
dispatch(spreadsheetActions.setLoadingIntegrationStatus(true));
let response = await spreadsheetManager.getIntegrationStatus();
batch(() => {
dispatch(spreadsheetActions.setLoadingIntegrationStatus(false));
dispatch(spreadsheetActions.setIntegrationStatus(response));
});
};
spreadsheetManager.js
getIntegrationStatus = async () => {
const getIntegrationStatusResult = await spreadsheetService.getIntegrationStatus();
return getIntegrationStatusResult;
};
spreadsheetService.js
getIntegrationStatus = async () => {
const integrationStatusResponse = await axios.get(
`${BASE_URL}/api/integration_status`
);
return integrationStatusResponse.data;
};
}
spreadsheetActions.js
export const setIntegrationStatus = rows => ({
type: SET_INTEGRATION_STATUS,
payload: rows
});
export const setLoadingIntegrationStatus = status => ({
type: SET_LOADING_INTEGRATION_STATUS,
payload: status
});
我的代码有什么问题?如何停止无限循环?
答案 0 :(得分:1)
通过创建具有三个可能值(未决,已实现和已拒绝)的新fetchStatus
状态来解决问题,然后在我中添加fetchStatus === 'pending'
的条件检查。
答案 1 :(得分:0)
我看到您正在对isEmpty进行答复,以检查是否应调用API。您可以检查isEmpty是否按预期工作,或者API始终返回空响应?
答案 2 :(得分:0)
该组件的预期功能是什么? API调用仅触发一次?
您的商店对isLoading标志的更新将在每次更改时导致渲染。目前,您的周期将是:
您是否已在控制台中记录了效果内的变量以及redux状态?如果Redux状态正在改变,则它会 在组件上触发渲染。
我认为最简单的解决方案是从依赖关系中删除isLoading标志,除非您有尝试实现的重试方案,但我正在寻找redux-saga的解决方案。