Combining AbortController timeout and unmount cleanup in useEffect fetch
0 reputation · 23 Mar 2023, 06:02 UTC
I'm configuring a data-fetching effect in React 18 that needs two cancellation paths: aborting the request when the component unmounts (or when dependencies change), and enforcing a client-side timeout since fetch has no built-in timeout option. My current design creates one AbortController inside useEffect, passes its signal to fetch, and calls abort() in the cleanup function.
The uncertainty is how to layer the timeout on top of this. If I add a setTimeout that calls abort() on the same controller, the cleanup function also calls abort(), so the two cancellation sources share one signal. I then need to distinguish a timeout abort from an unmount abort in the catch block, since both surface as AbortError, and I want to show a retry message only for the timeout case.
I'm also unsure whether the timeout timer should be cleared inside the effect cleanup alongside the abort call, or whether ordering matters to avoid aborting a request that already resolved.
Should I use a single controller for both unmount and timeout, or separate controllers with a combined signal? What is the correct cleanup ordering for the timer and abort call? And how can I reliably tell a timeout-triggered abort apart from an unmount-triggered one?