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.

eslint-plugin-react-hooks introduces a bug to minimal app unless overridden

See original GitHub issue

Following up on https://github.com/facebook/react/issues/14920

[ESLint] Feedback for ‘exhaustive-deps’ lint rule

…I believe I have a case which triggers the eslint rule and which creates a looping bug if the auto-fix is applied. I also propose a way the linting might be applied to resolve this.

I wrote a minimal app to explore the issue, to try to figure out an AST inspection which might mitigate the problem. Happy to refactor if you tell me an alternative way to present the backend server which would be preferred to an express dependency.

The app is a ‘row editor’ which edits rows from a backend, having an id and title. The UI offers a list of row links. The user can navigate to edit a row from the list or create a new row. The front end user is expected to edit the title field. However, the backend also needs to make changes(it adds the id value from the ‘database’ when a new record is saved).

There are two lines which require an override otherwise the app enters a loop between client and server, creating runaway saves and reloads and making the UI unusable. The override lines needed are at…

https://github.com/cefn/graphql-gist/blob/c0bece7e6b1fda832d57ccb363b1056f7cb2d37b/react-event-loop/client.js#L73 https://github.com/cefn/graphql-gist/blob/c0bece7e6b1fda832d57ccb363b1056f7cb2d37b/react-event-loop/client.js#L87

It could be possible to detect that setLocalRow is called within the body, and therefore allow a dependency of localRow to be commented in the array instead of declared.

Although the minimal client app is generic, the full example is quite detailed, because the async callbacks need a server endpoint to demonstrate the issue. Additionally, the interlocking concerns of e.g. navigating to rows, auto-saving rows, creating new rows contribute to defining the problem. With fewer features supported, the problem doesn’t arise.

The backend code is super-simple so hopefully doesn’t confuse. If there is a specific refactoring which would help, let me know as this codebase is purely there to demonstrate the issue.

npm install then npm run start then http://localhost:8080 should be enough to observe the working system. Removing the eslint overrides and then auto-fixing will show the issues which arise if the eslint rule is allowed to add localRow or remoteRow to the dependencies.

What is the current behavior?

A loop between client and server if the auto-fix is applied

What is the expected behavior?

The eslint rule should not introduce a dependency which causes a loop. For example, it could instead add a commented reference to localRow in the dependencies instead, to account for the case that setLocalRow is invoked in the body.

[localRow, remoteRow, saveItem]

…could look like… [ /localRow,/ remoteRow, saveItem]

This would allow the user to decide whether to leave the commented reference in place, or uncomment it to declare the dependency, knowing that it could create a loop. Either comment or reference would satisfy the rule.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

I observed the issue with “eslint-plugin-react-hooks”: “^2.0.1”

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
cefncommented, Dec 11, 2019

It’s inevitable that the linter has to examine the references within the useEffect() callback function in order to do its job, so if you choose to access references there when you don’t need to, it correctly assumes they are accessed in the useEffect for some functional reason - i.e. the access has to happen at the time useEffect runs.

If you implement an infinite loop by both accessing a changed variable and triggering a change to the variable within useEffect it will faithfully add the changed item to the variable list, which it must.

If the infinite loop is implemented in code outside the useEffect() (possibly via server-side code) it’s impossible for the linter to trace this.

In the original case I shared, the localRow useState() hook combined with use of setLocalRow within the useEffect() means it’s detectable by the linter that adding localRow to the variable list will cause an infinite loop. In my view a detectable infinite loop should be handled better by the linter (adding it as a commented item in the variable list, but allowing an uncommented item there to also satisfy the linter).

Does the auto-filling of props in the useEffect variables list stop if you declare the const outside useEffect (and hence don’t reference props within useEffect) ?

0reactions
gaearoncommented, Dec 11, 2019
Read more comments on GitHub >

github_iconTop Results From Across the Web

Bug Reporting - Apple Developer
Send us your feedback and report bugs. Developer feedback is vital to making the Apple ecosystem even better. With Feedback Assistant available on...
Read more >
PatternFly 4 • Release notes
PatternFly is Red Hat's open source design system. It consists of components, documentation, and code for building enterprise applications at scale.
Read more >
@material-ui/styles | Yarn - Package Manager
The introduction of deprecation messages in the next v4 minors. These messages will help developers upgrade to v5. A progressive bug fixes freeze...
Read more >
react-scripts: Versions - Openbase
Create React App 5.0.1 is a maintenance release that improves compatibility with React 18. We've also updated our templates to use createRoot and...
Read more >
The eslint-mdx from mdx-js - GithubHelp
If you're using multi languages, js/jsx/ts/tsx/vue , etc for example, you'd better to always use overrides feature of ESLint, because configs may be ......
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