Reputation: 127
I have a functional component lets say Offers.This component on load calls an api say api_1
. once the response of api_1
is received and is success I want to trigger another api call say api_2
and based on the response of api_2
want to show success screen
else error screen
. Also, in case api_1
fails i want to show error screen
const Offers =()=>{
const[api_1Success,setApi_1Success]=useState(null);
const[api_1Failure,setApi_1Failure]=useState(null);
const[api_1FetchComplete,setApi_1FetchComplete]=useState(null);
const[api_2Success,setApi_2Success]=useState(null);
const[api_2Failure,setApi_2Failure]=useState(null);
const[api_2FetchComplete,setApi_2FetchComplete]=useState(null);
const showSuccess =useCallback(() =>{
//sets some other state to render success page
},[api_2Success]);
const showError =useCallback(() =>{
//sets some other state to render error page
},[]);
const changeScreen = useCallback(() => {
if(api_2Success){
showSuccess();
} else {
showErrorScreen();
}
},[api_2Success,showSuccess,showErrorScreen]);
useEffect(()=>{ /** first useEffect **/
//dummy api call
dummyApiCall().then((response)=>{
setApi_1Success(response);
}).catch(ex=>(setApi_1Failure(ex))).finally(()=>(setApi_1FetchComplete(true)));
},[])
useEffect(()=>{ /** second useEffect **/
if(api_1FetchComplete){
if(api_1Success){
//dummy api call
dummyApiCall().then((response)=>{
setApi_2Success(response);
}).catch(ex=>(setApi_2Failure(ex))).finally(()=>(setApi_2FetchComplete(true)));
}
}
if(api_1Failure){
changeScreen();
}
},[
api_1FetchComplete,
api_1Failure,
api_1Success,
changeScreen,
])
useEffect(()=>{ /** third useEffect **/
if(api_2FetchComplete){
changeScreen();
}
},[api_2FetchComplete,changeScreen]);
return(....);
}
Now whenever response of api_2
is available 3rd useeffect runs as a result the changeScreen method changes as it is dependent on api_2success
.Now since changeScreen has changed 2nd useEffect gets called and the loop continues.
Is there any why i can avoid adding changeScreen in the dependency Array
Upvotes: 1
Views: 78
Reputation: 420
Creating an async/await
function could help to create and understand the asynchronous flow better:
useEffect(() => {
const getResponses = async () => {
try {
const response = await dummyApiCall();
setApi_1Success(response);
const response2 = await dummyApiCall();
setApi_2Success(response2);
} catch (error) {
changeScreen();
}
};
getResponses();
}, []);
Upvotes: 1