question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Bug: rules-of-hooks should support hooks inside top-level IIFEs

See original GitHub issue

React version: v16.13.1 eslint-plugin-react-hooks version: v3.0.0

Steps To Reproduce

  1. Write something like this:
const Component = () => {
  (() => {
    useState ();
  })()
};
  1. Run the rules-of-hooks linter rules on it.

The current behavior

Those linter rules will complain that the useState hook is being called inside a callback.

The expected behavior

Those linter rules should be a little smarter and ignore this kind of top-level IIFE “callback”, since if I’m understanding things correctly it’s completely safe to call hooks this way.

This is a bit of an edge case, but I’m wrapping some hook calls in an IIFE because I don’t want to be able to access the values they return directly, as they may not be the most up to date, rather than via the accessor my IIFE returns.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:11 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
gaearoncommented, Jul 27, 2020

This particular case is a rather exotic pattern and in my opinion isn’t worth adding complexity to the (already complex) rule implementation.

As an alternative with similar scoping “benefits”, you can use a block.

const Component = () => {
  let stuff;
  {
    useState();
    stuff = ...
  }
};
0reactions
iambryanhaneycommented, Jul 29, 2021

@wereHamster The above example could compose decently with expression chaining…

const categoryId = (GQL.useCategoriesQuery()[0].data?.categories ?? [])
   .find((x) => x.name === nameToCategory(name))?.id

If you need more complexity in a self-contained block, you could mimic the do expression proposal with your named IIFE…

const categoryId = (function Do() {
  const [res] = GQL.useCategoriesQuery()
  const options = res.data?.categories ?? []
  return options.find((x) => x.name === nameToCategory(name))?.id
})() 

I don’t feel like that’s any clunkier than an anonymous IIFE; it’s arguably more self-descriptive.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Rules of Hooks - React
Don't call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any...
Read more >
Trouble with React Hooks, which react hook rule am I breaking?
Don't call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function.
Read more >
Invalid hook call. Hooks can only be called inside the body of ...
React error “Invalid hook call. Hooks can only be called inside the body of a function component” occurs due to many reasons. Learn...
Read more >
Understanding common frustrations with React Hooks
React Hooks can be frustrating despite their popularity and widespread use. Learn about some of the drawbacks to using React Hooks.
Read more >
Rules of React Hooks - CoderPad
The top level of a functional component is the base of your function body before you return your JSX elements. This is where...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found