Skip to content

[bug] no-leaked-event-listener false positive when using AbortSignal via wrapper hook #1282

@TrevorBurnham

Description

@TrevorBurnham

Describe the bug

I use this convenience wrapper for when I want to add an event listener in a useEffect and remove it on cleanup:

/**
 * A wrapper around `useEffect` that automatically cleans up an event listener using AbortSignal.
 * Usage:
 *
 * useEventEffect((signal) => {
 *   window.addEventListener("scroll", () => {
 *     // do something
 *   }, { signal });
 * });
 */
export const useEventEffect = (
  effectHandler: (signal: AbortSignal) => void,
  deps: DependencyList,
) => {
  useEffect(() => {
    const controller = new AbortController();
    effectHandler(controller.signal);
    return () => {
      controller.abort();
    };
  }, deps); // eslint-disable-line react-hooks/exhaustive-deps
};

When I use addEventListener within that hook, it gets flagged by the rule, even though the listener is cleaned up by aborting the signal.

Reproduction

No response

Expected behavior

I think it would be reasonable to ignore any addEventListener call where signal is used. I see that signal is supported by the rule: #838 But the rule seems to be looking for the abort call within a limited scope.

I'd suggest that passing in a signal should be sufficient to satisfy the rule, since the linter can't reliably determine whether that signal will be aborted at the appropriate time.

Platform and versions

* @eslint-react/eslint-plugin v2.0.6
* Node.js v22.17.1

Stack trace


Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions