React: Lint rule for hooks report error for non hook function starting by `useXXX`

Created on 17 Dec 2019  Â·  3Comments  Â·  Source: facebook/react

Declaring non-hook function like:

import { useWith, identity } from "ramda";

const test = useWith(Math.pow, [identity, identity]);

causes

React Hook "useWith" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function.eslint(react-hooks/rules-of-hooks)

I'm using latest version of eslint-plugin-react-hooks 2.3.0

It would be useful to have settings to override this regexp.

https://github.com/facebook/react/blob/36a6e29bb3eead85e3500ba7269cbcd55516a8fb/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js#L11-L20

I can make PR for it if you think that this is a good idea.

Most helpful comment

How about rule config {ignores: [...patterns]} so that users can customize what they'd like to ignore. Doesn't seem fair to litter code with disable comments, especially when users are only likely to have a few functions they need ignored—and always every time they use them.

All 3 comments

In order to fix this, RulesOfHooks would have to be aware of actual valid hooks and not just the naming pattern for them. The question is: would keeping such a list in this repo be acceptable?

There's also the problem of custom hooks, where that list would not be sufficient to tell hooks from non-hooks apart.

Hooks rules rely on this convention, including for custom Hooks. We can't guess their names so we needed to squat some prefix that can reasonably be considered unique to Hooks. We tried to pick something that is both short enough and isn't used in the ecosystem widely at the same time. Unfortunately, there are a few false positive for use now, and this sucks for libraries that rely on it. But the whole Hooks convention falls apart if we can't reliably distinguish them at the build time. So a clash like this is the cost.

There's also de problem of custom hooks, where that list would not be sufficient to tell hooks from non-hooks apart.

That is not just an additional problem — it is the reason for the convention. Validating known ones is insufficient for the rule to work at scale.

Arguably now that Hooks are commonplace, even without the linter, seeing use outside a component makes you wonder — is this a Hook? Is this a violation? So while it's unfortunate for other libraries, I think we can accept by now that within React ecosystem, use prefix has a semantic meaning now. As a workaround and to clarify the intent, you can do:

import { useWith as ramdaUseWith, identity } from "ramda";

I know it's unfortunate but don't have a better option to offer. (Alternatively you can // eslint-disable-next-line.)

How about rule config {ignores: [...patterns]} so that users can customize what they'd like to ignore. Doesn't seem fair to litter code with disable comments, especially when users are only likely to have a few functions they need ignored—and always every time they use them.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sophiebits picture sophiebits  Â·  107Comments

acdlite picture acdlite  Â·  83Comments

brunolemos picture brunolemos  Â·  285Comments

gaearon picture gaearon  Â·  227Comments

gaearon picture gaearon  Â·  126Comments