Does not work for components that fetch based on props.
But using the AbortController object makes it work as intended.
import{useEffect,useRef,useReducer,useCallback}from"react";functionasyncReducer(state,action){switch(action.type){case"pending":{return{status:"pending",data:null,error:null};}case"resolved":{return{status:"resolved",data:action.data,error:null};}case"rejected":{return{status:"rejected",data:null,error:action.error};}default:{thrownewError(`Unhandled action type: ${action.type}`);}}}exportconstuseFetch=url=>{constisCurrent=useRef(false);const[state,dispatch]=useReducer(asyncReducer,{status:"idle",data:null,error:null,});useEffect(()=>{isCurrent.current=true;return()=>{// called when the component is going to unmountisCurrent.current=false;};},[]);constfetchURL=useCallback(controller=>{dispatch({type:"pending"});fetch(url,{signal:controller.signal,}).then(res=>res.json()).then(data=>{if(!isCurrent.current)return;dispatch({type:"resolved",data});}).catch(error=>{if(!isCurrent.current)return;dispatch({type:"rejected",error});});},[url]);useEffect(()=>{letcontroller=newAbortController();fetchURL(controller);return()=>controller.abort();},[fetchURL]);return{state,fetchURL};};
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Does not work for components that fetch based on props.
But using the AbortController object makes it work as intended.