Rules Hub
Coding Rules Library
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Prefer AbortController over manual flags for effect cleanup
Use AbortController to handle async cleanup in useEffect instead of manual boolean flags like isActive or isMounted.
Bad example
| 1 | useEffect(() => { |
| 2 | let isActive = true; |
| 3 | const controller = new AbortController(); |
| 4 |
|
| 5 | fetch('/api/data', { signal: controller.signal }) |
| 6 | .then((res) => res.json()) |
| 7 | .then((data) => { |
| 8 | if (isActive) { |
| 9 | setData(data); |
| 10 | } |
| 11 | }); |
| 12 |
|
| 13 | return () => { |
| 14 | isActive = false; |
| 15 | controller.abort(); |
| 16 | }; |
| 17 | }, []); |
Explanation (EN)
Using a manual `isActive` flag alongside `AbortController` is redundant. The flag adds imperative complexity solely to prevent state updates on unmounted components, which `AbortController` can already handle.
Objašnjenje (HR)
Korištenje ručne zastavice `isActive` uz `AbortController` je suvišno. Zastavica dodaje imperativnu složenost samo kako bi spriječila ažuriranje stanja na demontiranim komponentama, što `AbortController` već rješava.
Good example
| 1 | useEffect(() => { |
| 2 | const controller = new AbortController(); |
| 3 |
|
| 4 | fetch('/api/data', { signal: controller.signal }) |
| 5 | .then((res) => res.json()) |
| 6 | .then((data) => setData(data)) |
| 7 | .catch((error) => { |
| 8 | if (error.name !== 'AbortError') { |
| 9 | setError(error); |
| 10 | } |
| 11 | }); |
| 12 |
|
| 13 | return () => controller.abort(); |
| 14 | }, []); |
Explanation (EN)
By relying solely on `AbortController`, the request is cancelled upon unmount, causing the promise to reject with an `AbortError`. This naturally prevents the success callback from running, removing the need for an extra variable.
Objašnjenje (HR)
Oslanjanjem isključivo na `AbortController`, zahtjev se otkazuje pri demontiranju, uzrokujući odbijanje obećanja s `AbortError`. To prirodno sprječava izvršavanje uspješnog callbacka, uklanjajući potrebu za dodatnom varijablom.
Exceptions / Tradeoffs (EN)
If AbortController isn't available in the target runtime, a simple mounted flag can be acceptable. For complex multi-step cancellations, a higher-level abstraction may be clearer.
Iznimke / Tradeoffi (HR)
Ako AbortController nije dostupan u ciljnom okruženju, jednostavan mounted flag može biti prihvatljiv. Za složenija otkazivanja kroz više koraka, bolja je viša apstrakcija.