Gelio / tslint-react-hooks

TSLint rule for detecting invalid uses of React Hooks

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Early return?

esamattis opened this issue Β· comments

This should be error right?

    if (thing) {
        return;
    }

    const [state, setState] = useState(null);

Right, that is correct πŸ‘ Thanks for pointing it out! This is a very interesting case that I did not think of beforehand.

I will try to cover this case in the nearest future

This would be fantastic - our developers make this mistake all the time! Big thanks for putting tslint-react-hooks together in the first place.

commented

Any news on this? I think it'd be a great addition. πŸ‘

I'm not sure whether early returns are a problem. From the hooks rules:

React relies on the order in which Hooks are called.

So, it's a problem if subsequent renders call hooks [A, B, C] and then [A, C].

What if the sequence is consistent, but terminates early? E.g., [A, B, C, D] and then [A, B, C]? Unclear.

FWIW we've been returning early and haven't had any problems with it yet.

commented

It's a problem. It's even in the official eslint plugin too:

[eslint] React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return? (react-hooks/rules-of-hooks)

Example

const App = () => {
  const [foo, setFoo] = useState('')

  if (true) {
    return 'nope'
  }

  // v ---- Error appears here
  useEffect(() => {
    setFoo('b')
  }, [])

  return 'yes'
}

And it looks like this during runtime:

image

Yea, I got burned by this error couple times too. Sometimes it's really hard to spot where the issue is so it would be super helpful to have a lint for that.

Good news πŸ˜„ I just published tslint-react-hooks@2.0.0-alpha.1 that reports violations for hooks used after early returns.

You can install it with:

npm install tslint-react-hooks@2.0.0-alpha.1 --save-dev

I am looking for your opinions πŸ˜„ Let me know if it works fine for you after installing the latest alpha.

If everything is good, I will release 2.0.0 to the public

commented

Awesome! I've just tested it and seems to work, I will report back if I find anything!

commented

I think I found an issue. The following doesn't work:

// Doesn't work
export const useRouter = () => {
  return useContext(RouterContext)
}

// Doesn't work either
export function useRouter() {
  return useContext(RouterContext)
}

The error is thrown:

A hook should not appear after a return statement (react-hooks-nesting)

However, this works:

// Works
export const useRouter = () => useContext(RouterContext)

The fact that we have a return which returns the useContext appears to be the problem.

Right, I missed that kind of obvious case πŸ˜„

I guess

function useRouter = () => {
  const router = useContext(RouterContext);
  return router;

would work just fine.

That is due to a flaw in the current implementation. Upon encountering a return statement, all following hooks will be marked as violations. In this case, return is just before the hook, which of course should not be a problem. I will try to come up with a fix today πŸ˜„ I will post an update and publish a new alpha version

Thank you for testing ❀️

I have just released v2.0.0-alpha.2. It should no longer report rule violations when using hooks in return statements.

You can install it with

npm install tslint-react-hooks@2.0.0-alpha.2

@mikfoo if you would be so kind and verify that it works for you πŸ˜„

commented

@Gelio just tested and seems to work!

commented

By the way, consider using tagging when publishing packages (npm publish --tag alpha). Right now the alpha is actually in the latest branch, so if you run npm install tslint-react-hooks it actually installs the alpha version. :)

@Gelio just tested and seems to work!

Great πŸ‘ I will release 2.0.0 later today. Thank you for testing

By the way, consider using tagging when publishing packages (npm publish --tag alpha). Right now the alpha is actually in the latest branch, so if you run npm install tslint-react-hooks it actually installs the alpha version. :)

I know something was off when I noticed 2.0.0-alpha.2 in the badge in the readme πŸ˜„ Thanks for the info, I thought npm would treat it as an alpha immediately πŸ˜„

I have just published tslint-react-hooks@2.0.0. It fixes the problem, therefore I am closing the issue.

Please feel free to open new issues if upon encountering bugs or other problems with the implementation