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

react-hooks/rules-of-hooks: Add support for do/while loops #28714

Merged
merged 5 commits into from
Oct 22, 2024

Conversation

tyxla
Copy link
Contributor

@tyxla tyxla commented Apr 2, 2024

Summary

Currently, react-hooks/rules-of-hooks does not support do/while loops - I've also reported this in #28713.

This PR takes a stab at adding support for do/while by following the same logic we already have for detecting while loops.

After this PR, any hooks called inside a do/while loop will be considered invalid.

We're also adding some unit tests to confirm that the behavior is working as expected.

Fixes #28713.

How did you test this change?

I've added unit tests that cover the case and verified that they pass by running:

yarn test packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js --watch

I've also verified that the rest of the tests continue to pass by running:

yarn test

and

yarn test --prod

@facebook-github-bot
Copy link

Hi @tyxla!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at [email protected]. Thanks!

@tyxla tyxla changed the title Fix/rule of hooks do while react-hooks/rules-of-hooks: Add support for do/while loops Apr 2, 2024
@react-sizebot
Copy link

react-sizebot commented Apr 2, 2024

Comparing: ae90522...ff8ac24

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.js = 6.68 kB 6.68 kB = 1.82 kB 1.82 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 506.86 kB 506.86 kB = 90.71 kB 90.71 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.69 kB 6.69 kB +0.05% 1.83 kB 1.83 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js = 511.79 kB 511.79 kB = 91.43 kB 91.42 kB
facebook-www/ReactDOM-prod.classic.js = 604.26 kB 604.26 kB = 106.92 kB 106.92 kB
facebook-www/ReactDOM-prod.modern.js = 580.48 kB 580.48 kB = 103.00 kB 103.01 kB

Significant size changes

Includes any change greater than 0.2%:

(No significant changes)

Generated by 🚫 dangerJS against 0f822bf

@tyxla
Copy link
Contributor Author

tyxla commented Apr 17, 2024

@eps1lon I noticed you've been working on the ESLint rules, will you have a chance to take a look? Thanks 🙌

Copy link

This pull request has been automatically marked as stale. If this pull request is still relevant, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize reviewing it yet. Your contribution is very much appreciated.

@github-actions github-actions bot added the Resolution: Stale Automatically closed due to inactivity label Jul 16, 2024
Copy link

Closing this pull request after a prolonged period of inactivity. If this issue is still present in the latest release, please ask for this pull request to be reopened. Thank you!

@github-actions github-actions bot closed this Jul 23, 2024
@tyxla
Copy link
Contributor Author

tyxla commented Jul 23, 2024

Bump! This is still a relevant addition to the existing ESLint plugin IMHO.

@tyxla
Copy link
Contributor Author

tyxla commented Jul 23, 2024

cc @mofeiZ perhaps? Sorry for the direct ping, but no one ever replied to this one, and I still think it's useful.

@josephsavona
Copy link
Contributor

We need to figure out our strategy for the ESLint plugin. React Compiler also implements the conditional hook call check for all loop types, using a robust general-purpose approach based on the control flow graph. Long-term we expect to replace the existing plugin w the compiler-powered version.

But we can take a look and see if it makes sense to proceed here in the meantime. I haven’t had a chance to look at the code yet though.

@josephsavona josephsavona reopened this Jul 23, 2024
Copy link

vercel bot commented Jul 23, 2024

@tyxla is attempting to deploy a commit to the Meta Open Source Team on Vercel.

A member of the Team first needs to authorize it.

@tyxla
Copy link
Contributor Author

tyxla commented Jul 23, 2024

Thank you @josephsavona 🙌

FWIW, we're also interested in leveraging the React Compiler eslint plugin (we've been experimenting with it), and I'd be happy to come up with a fix for it if that same bug is present. Sounds like a good opportunity to learn more about its codebase.

@github-actions github-actions bot removed the Resolution: Stale Automatically closed due to inactivity label Jul 23, 2024
@josephsavona
Copy link
Contributor

I'd be happy to come up with a fix for it if that same bug is present

I appreciate the offer! But what I meant is that React Compiler already correctly handles do..while and all other forms of loops when detecting conditional hooks. But definitely try it out and let us know if you see any issues!

In the meantime we’ll review the code here.

@tyxla
Copy link
Contributor Author

tyxla commented Jul 23, 2024

React Compiler already correctly handles do..while and all other forms of loops when detecting conditional hooks.

That's even better, thanks for clarifying!

Copy link

This pull request has been automatically marked as stale. If this pull request is still relevant, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize reviewing it yet. Your contribution is very much appreciated.

@github-actions github-actions bot added the Resolution: Stale Automatically closed due to inactivity label Oct 21, 2024
@tyxla
Copy link
Contributor Author

tyxla commented Oct 21, 2024

Not stale IMHO.

@github-actions github-actions bot removed the Resolution: Stale Automatically closed due to inactivity label Oct 21, 2024
Copy link
Contributor

@mofeiZ mofeiZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tyxla left a few questions. I agree with @josephsavona, react compiler-based eslint does correctly detect and fix this, but we know that not everyone has upgraded yet

@tyxla tyxla force-pushed the fix/rule-of-hooks-do-while branch from 33a8918 to 33cb28f Compare October 22, 2024 10:04
Copy link

vercel bot commented Oct 22, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
react-compiler-playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 22, 2024 5:14pm

@tyxla
Copy link
Contributor Author

tyxla commented Oct 22, 2024

@mofeiZ, thanks for the review and the valuable feedback!

I've addressed it all, and this PR should be ready for one last look. 👀

@tyxla tyxla requested a review from mofeiZ October 22, 2024 10:18
Copy link
Contributor

@mofeiZ mofeiZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the fix and new test fixtures @tyxla!

@mofeiZ mofeiZ merged commit 9daabc0 into facebook:main Oct 22, 2024
184 checks passed
github-actions bot pushed a commit that referenced this pull request Oct 22, 2024
<!--
  Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.

Before submitting a pull request, please make sure the following is
done:

1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
  2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
  9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
  10. If you haven't already, complete the CLA.

Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->

## Summary

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->

Currently, `react-hooks/rules-of-hooks` does not support `do/while`
loops - I've also reported this in
#28713.

This PR takes a stab at adding support for `do/while` by following the
same logic we already have for detecting `while` loops.

After this PR, any hooks called inside a `do/while` loop will be
considered invalid.

We're also adding some unit tests to confirm that the behavior is
working as expected.

Fixes #28713.

## How did you test this change?

<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
  If you leave this empty, your PR will very likely be closed.
-->

I've added unit tests that cover the case and verified that they pass by
running:

```
yarn test packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js --watch
```

I've also verified that the rest of the tests continue to pass by
running:

```
yarn test
```

and

```
yarn test --prod
```

DiffTrain build for [9daabc0](9daabc0)
@tyxla tyxla deleted the fix/rule-of-hooks-do-while branch October 23, 2024 08:01
@Mathias-S
Copy link

Mathias-S commented Dec 10, 2024

FYI, this change causes false positives when for/while loops are used in functional components, see #31687

Example of code that now gets (incorrectly) flagged by this rule:

const MyComponent = () => {
  const [state, setState] = useState(0);

  for (let i = 0; i < 10; i++) {
    console.log(i);
  }

  return <div></div>;
};

@tyxla
Copy link
Contributor Author

tyxla commented Dec 10, 2024

@Mathias-S thanks for the report! We might need to take this a different way.

I think I might have a quick solution as I played with a few alternative solutions before. Stay tuned.

@tyxla
Copy link
Contributor Author

tyxla commented Dec 10, 2024

Follow up fix in #31720, @Mathias-S please take a look when you get a chance.

tschaub added a commit to planetlabs/eslint-config-planet that referenced this pull request Jan 8, 2025
The latest release of eslint-plugin-react-hooks incorrectly flags uses of hooks as occurring in a loop if a component function body contains a loop.

Downgrading to version 5.0.0 is a workaround until the React team publishes a release with the fix in facebook/react#28714 (merged but not yet released).

See facebook/react#31687
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bug: react-hooks/rules-of-hooks does not support do/while loops
7 participants