Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: rules-of-hooks ESLint rule not catching conditional hooks in React.memo() (Typescript) #19117

Closed
zachkirsch opened this issue Jun 11, 2020 · 2 comments
Labels
Component: ESLint Rules Resolution: Expected Behavior Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@zachkirsch
Copy link

I've noticed that the "no conditional hooks" aspect of the rules-of-hooks eslint rule isn't working inside a React.memo()'ed component. The project is typescript and I'm using the parse from @typescript-eslint/parser, so I'm not sure if the problem is with the rule or with the parser.

React version:

Steps To Reproduce

  1. Create a component using React.memo() inside a Typescript project
  2. Add a hook that is called conditionally, e.g.
export const MyMemoizedComponent = React.memo((props: {}) => {
  if (Math.random() > 0.5) {
    React.useEffect(() => {}, []);
  }
  return <div />;
});

Link to code example: https://codesandbox.io/s/no-rules-of-hooks-warning-in-typescript-reactmemo-ei00n?file=/src/index.tsx

The current behavior

ESLint does not show any errors.

The expected behavior

ESLint should show an error like React Hook "React.useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render.

@zachkirsch zachkirsch added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Jun 11, 2020
@zachkirsch zachkirsch changed the title Bug: rules-of-hooks ESLint rule not failing in React.memo() (in Typescript) Bug: rules-of-hooks ESLint rule not catching conditional hooks in React.memo() (Typescript) Jun 19, 2020
@zachkirsch zachkirsch reopened this Jul 15, 2020
@jackmccloy
Copy link

+1ing just to confirm that I'm seeing the same behavior

@eps1lon
Copy link
Collaborator

eps1lon commented Sep 19, 2021

Thanks for the feedback.

The rules of hooks are only enforced for

Calls to Hooks are either inside a PascalCase function (assumed to be a component) or another useSomething function (assumed to be a custom Hook).

-- https://reactjs.org/docs/hooks-faq.html#what-exactly-do-the-lint-rules-enforce

So you should name your function to get the rule to work. This also helps debugging since your inner component wouldn't have a display name otherwise.

export const MyMemoizedComponent = React.memo((props: {}) => {
export const MyMemoizedComponent = React.memo(function MyComponent(props: {}) {
  if (Math.random() > 0.5) {
    React.useEffect(() => {}, []);
  }
  return <div />;
});

Duplicate of #20408, #20448

@eps1lon eps1lon closed this as completed Sep 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: ESLint Rules Resolution: Expected Behavior Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

3 participants