Skip to content

feat(useAsyncEffect): provide an AbortSignal to the effect and abort it on cleanup#385

Open
haejunejung wants to merge 1 commit into
toss:mainfrom
haejunejung:feat/use-async-effect-abort-signal
Open

feat(useAsyncEffect): provide an AbortSignal to the effect and abort it on cleanup#385
haejunejung wants to merge 1 commit into
toss:mainfrom
haejunejung:feat/use-async-effect-abort-signal

Conversation

@haejunejung

Copy link
Copy Markdown

Overview

solve #220

Enhances useAsyncEffect to create an AbortController for each effect run and pass its signal to the effect. The signal is aborted on unmount or dependency change, so in-flight async work (such as fetch) can be cancelled without extra boilerplate.

  • effect(signal) — passes an AbortSignal to the effect
  • Calls controller.abort(reason) on cleanup (optional reason argument supported)
  • Backward compatible — callbacks that ignore the signal keep working

Checklist

  • Did you write the test code?
  • Have you run yarn run fix to format and lint the code and docs?
  • Have you run yarn run test:coverage to make sure there is no uncovered line?
  • Did you write the JSDoc?

Copilot AI review requested due to automatic review settings June 14, 2026 07:06
@changeset-bot

changeset-bot Bot commented Jun 14, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 5faa0f6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
react-simplikit Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds AbortSignal support to useAsyncEffect so async work can be canceled on cleanup (unmount/deps change), and documents + tests the new behavior.

Changes:

  • Pass an AbortSignal into the async effect and abort it during cleanup (optionally with a reason).
  • Extend unit tests to validate signal passing/aborting and dependency-change teardown behavior.
  • Add a changeset announcing the new capability.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
packages/core/src/hooks/useAsyncEffect/useAsyncEffect.ts Create/abort an AbortController per run and pass signal into the effect; update JSDoc and signature.
packages/core/src/hooks/useAsyncEffect/useAsyncEffect.spec.ts Add tests covering AbortSignal, abort-on-unmount, abort-on-deps-change, and abort reason.
.changeset/useasynceffect-abort-signal.md Publish minor release note for AbortSignal support and abort reason parameter.
Comments suppressed due to low confidence (2)

packages/core/src/hooks/useAsyncEffect/useAsyncEffect.ts:1

  • The primary example still shows an effect callback with no parameters, but the JSDoc now documents the callback as (signal: AbortSignal) => .... Even though callers can ignore the parameter, this is confusing for readers. Update the example to accept signal (or _signal) to match the documented API, or explicitly mention in the docs that the parameter can be omitted/ignored.
import { DependencyList, useEffect } from 'react';

packages/core/src/hooks/useAsyncEffect/useAsyncEffect.ts:56

  • If the async effect rejects (including common cases like fetch rejecting with AbortError after abort()), this creates an unhandled promise rejection because there is no .catch(...). Consider attaching a rejection handler: at minimum, suppress rejections that occur after the signal was aborted; and for non-abort errors, report them (e.g., console.error) so they don't silently fail or crash environments configured to treat unhandled rejections as fatal.
    effect(abortController.signal).then(result => {
      cleanup = result;
      if (isCleaned) {
        cleanup?.();
      }
    });

reason?: unknown
) {
useEffect(() => {
const abortController = new AbortController();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants