react
react copied to clipboard
eslint react-hooks/rulesOfHooks: add rule to check for non-function return from useEffect
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+
This has nothing to do with rules of hooks. What you want is type checking, that is what TypeScript is for
@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.
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.
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() );
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.
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!
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!