react icon indicating copy to clipboard operation
react copied to clipboard

eslint react-hooks/rulesOfHooks: add rule to check for non-function return from useEffect

Open jlbooker opened this issue 1 year ago • 6 comments

Feature request: Could we add an eslint rule to eslint-plugin-react-hooks to show an error when a non-function value is returned from within a useEffect call?

For the function passed to the useEffect hook, valid return statements are: return; (no value) return undefined; (unnecessarily verbose, but still valid) return () => { [...cleanup function... ] }

Returning anything else will cause the error: Uncaught TypeError: destroy is not a function at runtime.

The dev UX of this isn't great, as it can be hard to find the return statement from the backtrace, even with source maps enabled. Particularly in regards to upgrading to React 18 -- It seems React 17 was more tolerant of incorrect return values, but as I'm upgrading a codebase to React 18, these errors are now coming to light.

React version: 18+

jlbooker avatar Mar 22 '23 20:03 jlbooker

This has nothing to do with rules of hooks. What you want is type checking, that is what TypeScript is for

vkurchatkin avatar Mar 23 '23 11:03 vkurchatkin

@vkurchatkin Yes, a realize a full and complete solution to this requires a type checking system to fully evaluate the return type. However, it seems there are at least a few cases we could check for with lint rules, and that would handle 95% of the basic cases. For example, I came upon uses return "none"; and return null;, which are clearly not allowed and easily caught by a lint rule. Anything other than a bare return, undefined, or an arrow function is probably an error.

jlbooker avatar Mar 23 '23 13:03 jlbooker

I opened a related issue in the DT repo, for reference: https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/65890. Unfortunately, the types as they exist aren't strong enough to prevent crashes.

noahtallen avatar Jun 27 '23 21:06 noahtallen

Looks like it is simply impossible to catch this type of issue with TS, which is suuuper unfortunate.

Honestly, I really wish that React didn't crash here. IMO, it's unlikely that most expect a return value to do anything at all. For example, inline callbacks:

// returns whatever `doSomething` returns, or false, but I wouldn't expect the return value to do anything

useEffect( () => checkSomething && doSomething() );

noahtallen avatar Jul 06 '23 21:07 noahtallen

Any update on this issue ? With React 18 it looks like return undefined; or doing a return ; is also crashing, which was not the case in React 17. We have a huge code base, and there is no way I can do a regexp that complicated, and a global search of all useEffects is not even an option.

maximejen avatar Jan 23 '24 09:01 maximejen

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

github-actions[bot] avatar Apr 22 '24 10:04 github-actions[bot]

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you!

github-actions[bot] avatar Apr 29 '24 11:04 github-actions[bot]