Reactjs 阻止发送请求两次react redux(挂钩)
我有一些从api获取countries数组的钩子:Reactjs 阻止发送请求两次react redux(挂钩),reactjs,react-redux,react-hooks,Reactjs,React Redux,React Hooks,我有一些从api获取countries数组的钩子: import { useSelector, useDispatch } from 'react-redux' const useCountries = () => { const dispatch = useDispatch() const { countries } = useSelector(data => data) useEffect(() => { if (!countries.length) {
import { useSelector, useDispatch } from 'react-redux'
const useCountries = () => {
const dispatch = useDispatch()
const { countries } = useSelector(data => data)
useEffect(() => {
if (!countries.length) {
dispatch(getCountries())
}
}, [countries])
return {
countries
}
}
我有一些组件不在同一个DOM级别上,并且彼此不相关
const FirstComponent = () => {
const {countries} = useCountries()
// some using of countries array
}
const SecondComponent = () => {
const {countries} = useCountries()
// some using of countries array
}
当页面加载时,将执行这些组件中的2个,并调度2个操作。因为在第一个和第二个组件中还没有选择国家,所以它调用API请求。我的问题是,如果发送了某个请求,如何防止发送第二个请求。制定只发送一次请求的规则,如果尝试发送第二个请求,则阻止它。或者,在我的情况下,正确的解决方案或方法是什么
另外,我也试过这样一个案例:
const {
external: { response, isInitial }
} = useSelector(data => data)
useEffect(() => {
if (!response && isInitial) {
dispatch(setIsInitial(false))
fetch()
.then(res => res.json())
.then(data => {
setResponse(data)
})
}
}, [dispatch, response, isInitial])
这是我的减速机:
const initialState = {
response: null,
isInitial: true
}
export default function external(state = initialState, action) {
switch (action.type) {
case types.SET_RESPONSE:
return {
...state,
response: action.payload.data
}
case types.SET_INITIAL:
return {
...state,
isInitial: action.payload.data
}
default:
return state
}
}
但它会发送2个请求您可以修改您的
使用国
,如下所示:
const useCountries = () => {
const dispatch = useDispatch()
const countries = useSelector(state => state.countries);
const isFetching = useSelector(state => state.isFetching);
useEffect(() => {
if (!countries.length && !isFetching) {
dispatch(getCountries())
}
}, [countries, isFetching])
return {
countries
}
}
您需要在getCountries
函数中翻转isFetching
标志,并在api
解析后再次翻转它
------------------附加信息后编辑-----------------------
您需要将分派呼叫链接起来。这是为了确保在进行api调用之前设置该标志
要实现这一点,您可以通过以下方式使分派表格
dispatch
返回以下两种情况之一:
对于同步操作(如分派({type:'action'}),它将返回
操作对象({type:'action'}在我的示例中)
对于thunk动作(返回函数的动作创建者),它返回
从操作创建者返回相同的结果
这是第一例
const syncAction = (arg1, arg2) => {
return (dispatch, getState) => {
return Promise.resolve(arg1 + arg2);
}
}
这将是第二种情况
const asyncAction = (arg1, arg2) => {
return (dispatch, getState) => {
return fetch(/* some request */)
.then(response => dispatch({ type: "RESPONSE_RECEIVED", payload: response }));
};
};
现在,使用上面的两个选项,您可以执行以下操作:
dispatch(syncAction(...args)).then(() => {
dispatch(asyncAction())
});
在您的情况下,syncAction-isInitial
和asyncAction-getCountries()
添加调度
,以使用Effect dependencies数组来解决问题
const dispatch = useDispatch()
const { countries } = useSelector(data => data)
useEffect(() => {
if (!countries.length) {
dispatch(getCountries())
}
}, [countries, dispatch])
你可以有一个fetching
标志。另外,你可以编写逻辑,这样只有当state没有值或者你需要刷新state并且fetching不是true时才会调用api。你能附上一些代码解决示例吗,请针对我的情况!发布了一个答案。你的意思是分派一些将isFetching设置为true的操作吗?它将l不起作用,因为这些钩子几乎会同时被调用,您能展示一下如何在reducer中设置isFetching吗?dispatch
在本质上总是同步的。您可以有一个专门设置标志的dispatch
。您可以在进行api调用之前dispatch
。这样,只有一个dispatch。另一个将通过useEffect进行干运行,因为它不会进入if
块。您可以将减速机添加到帖子中。我将编辑它。您需要链接调度
调用,我将在我的答案中添加示例。导出函数setIsInitial(){return(dispatch,getState)=>{const{external}=getState()如果(external.isInitial){return Promise.resolve(dispatch({type:types.SET_是_INITIAL_SUCCESS,payload:{data:false}}))}返回Promise.reject()}谢谢,你帮了我很多忙