[bug] no-leaked-event-listener false positive when using AbortSignal via wrapper hook
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
Another false positive for this rule is BackHandler from react-native.
BackHandler.addEventListener returns a remove method, but the rules complains when it is used.
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.
I agree to this change. A PR is welcome.
Another false positive for this rule is
BackHandlerfromreact-native.
BackHandler.addEventListenerreturns aremovemethod, but the rules complains when it is used.
@SuperKXT Thank you for reporting it. This should be worth opening a separate issue.