-
Notifications
You must be signed in to change notification settings - Fork 47.2k
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
eslint-plugin-react-hooks & "Flat Config" (ESLint 9) #28313
Comments
Thank you for reaching out. What would be involved in creating such a wrapper? Does it make more sense to file a PR and then see how it'll look? We're only on ESLint 7 though so I guess we need to upgrade that first to test. |
It's not too much work (famous last words, I know). In theory the plugin should be able to get away with exporting an object containing
👍
Yeah it feels like it'd probably be cleanest to upgrade to ESLint 8 first, just in case any breaking changes impact the plugin. |
Note that even wiring up the plugin manually doesn't enable it to work with the now-released ESLint 9: the plugin currently uses APIs like e.g.
|
Eslint officially released v9.0.0 today. However, the Hope you'll add support for v9 soon! |
Should we raise a separate issue for v9 API support? |
Currently under discussion in jsx-eslint/eslint-plugin-react#3699. |
ESLint v9 support will be done in #28773 |
@eps1lon how far away from merge/release is this update to support eslint v9? |
Hey @eps1lon, greetings! I just wanted to ask, is #28773 part of the I am currently in the process of migrating to flat config, and the plugin is giving me an error.
If needed, here is a my repository where the issue can be reproduced by running https://github.com/virtuallyunknown/eslint-flat-config-migration Relevant files: Cheers! |
got the same error and I turn off the rules about react-hooks... |
The issue seems to have been resolved in the canary release. If you are using |
ESLint v9 support is available in the Canary release channel (earliest version 5.1.0-canary-cb151849e1-20240424) and will be released as stable with the stable release of React 19. |
I am not sure if this feedback is of any value, but it looks like the types from // @ts-check
// @typescript-eslint/utils: 7.7.1
// eslint-plugin-react-hooks: 5.1.0-canary-cb151849e1-20240424
import eslintPluginReactHooks from 'eslint-plugin-react-hooks';
/** @type {import('eslint').Linter.FlatConfig[]} */
export const configuration1 = [
{
plugins: {
'react-hooks': eslintPluginReactHooks
}
}
];
/** @type {import('@typescript-eslint/utils').TSESLint.FlatConfig.ConfigFile} */
export const configuration2 = [
{
plugins: {
'react-hooks': eslintPluginReactHooks
}
}
]; I don't want to paste the error message because it's a giant wall of text, but feel free to try it on your own. This appears to be a type error only, and as far as I can tell the plugin is working as expected, so thanks for the updates, much appreciated! |
Works great, thank you!!! If anyone needs a reference, this is how I got it working… https://github.com/MetroStar/comet-starter/blob/d4e97fb56a73f61656d2cd23eca158772d8d1429/eslint.config.js#L50 |
For follow up about when I can finally update to v9: facebook/react#28313 v8 reaches EOL in october
ESLint v9 is now supported, but the original issue here was about adding a flat-config helper and/or documentation. Are those still being worked on? I assume that's why this issue is still open. |
|
Thanks a lot. It works well. Hope there's nothing breaking 🤞🏻 |
|
What about it doesn't work in v9 when not using flat config? You have to disable flat config in v9 to use the config that's in the documentation. |
It looks like the issue with tseslint persists, but the rule does work as intended, |
Edit: you're right. I missing that piece. I'm going to delete my answer, as it's not really relevant. |
I have a setup with typescript-eslint, eslint-plugin-react-hooks and a bunch of other stuff, and it had been that way since May this year. Just updated everything to latest now, and it's still working, including Here is a link to the repository. You can clone it, run Only posting this here in case someone is struggling and finds this helpful. |
5.1.0 looks stable. I got this working once on a canary 5.1 but now in a new project with import pluginJs from '@eslint/js'
import tseslint from 'typescript-eslint'
import pluginReact from 'eslint-plugin-react'
import pluginReactHooks from 'eslint-plugin-react-hooks' // added
/** @type {import('eslint').Linter.Config[]} */
export default [
{ files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'] },
pluginJs.configs.recommended,
...tseslint.configs.recommended,
pluginReact.configs.flat.recommended,
pluginReactHooks.configs.flat.recommended, // added
]
It's not picking up depedency issues in a hook. Edit: I see there's a |
After using it for a week now, I've not faced any issues. Linting works well. Some of you here are pointing out that deps check isn't working as expected. I don't seem to have any, since its correctly pointing out the missing deps from my useEffect (rule : react-hooks/exhaustive-deps). So, what do y'all mean by deps check not working as expected ? Or am I missing something ? |
I think users just want this plugin to add flat configuration and update the documentation 🙏 I just want to connect it like other plugins, as @dominictobias described above 👍
|
@pkolt Same. Even I waited for sometime, for the provision to use flat config. But looks like its gonna take more time and I cannot rollback to older eslint config. So, I went ahead with the below config, based on this reply. My config probably still needs some work w.r.t ordering and extendability for other plugins, but this is working absolutely great for me. //eslint.config.mjs
import globals from 'globals';
import pluginJs from '@eslint/js';
import tseslint from 'typescript-eslint';
import pluginReact from 'eslint-plugin-react';
import pluginReactHooks from 'eslint-plugin-react-hooks';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
import unusedImports from 'eslint-plugin-unused-imports';
export default [
pluginJs.configs.recommended,
{
files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'],
settings: {
react: {
version: 'detect'
}
},
languageOptions: {
parserOptions: {
ecmaFeatures: {
jsx: true
}
}
}
},
{
ignores: ['**/dist/*', '**/*.config.{js,mjs,cjs,ts}', '**/node_modules/*']
},
{ languageOptions: { globals: globals.browser } },
...tseslint.configs.recommended,
pluginReact.configs.flat.recommended,
eslintPluginPrettierRecommended,
{
plugins: {
'react-hooks': pluginReactHooks
},
rules: {
'react/react-in-jsx-scope': 'off',
...pluginReactHooks.configs.recommended.rules
},
ignores: ['*.test.tsx']
},
// Custom Rules should be added below so that they overwrite any defaults in the above default setup
{
plugins: {
'unused-imports': unusedImports
},
rules: {
// Keep the below 3 rules turned off, so that unused-imports can do its job.
'react/react-in-jsx-scope': 'off',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'unused-imports/no-unused-imports': 'error',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_'
}
],
// Disable prop-types check as we are using typescript everywhere (Can be enabled again if we need runtime type checking)
'react/prop-types': [0]
}
}
]; |
Thanks! Not sure why it isn't in the docs but I got it to work with your code, for the tl;dr: import pluginJs from '@eslint/js'
import tseslint from 'typescript-eslint'
import pluginReact from 'eslint-plugin-react'
import pluginReactHooks from 'eslint-plugin-react-hooks'
/** @type {import('eslint').Linter.Config[]} */
export default [
{ files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'] },
pluginJs.configs.recommended,
...tseslint.configs.recommended,
pluginReact.configs.flat.recommended,
{
plugins: {
'react-hooks': pluginReactHooks,
},
rules: {
'react/react-in-jsx-scope': 'off',
...pluginReactHooks.configs.recommended.rules,
},
},
] |
@dominictobias Great ! I think you probably missed these two comments in this issue, while looking for solutions : |
Maybe this will be useful to someone, I settled on this configuration for the project and it works 👍 // eslint.config.js
import globals from 'globals';
import pluginJs from '@eslint/js';
import tseslint from 'typescript-eslint';
import pluginReact from 'eslint-plugin-react';
import pluginRefresh from 'eslint-plugin-react-refresh';
import pluginHooks from 'eslint-plugin-react-hooks';
/** @type {import('eslint').Linter.Config[]} */
export default [
{ ignores: ['dist'] },
{
files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'],
settings: {
react: {
version: 'detect',
},
},
languageOptions: {
globals: globals.browser,
},
},
pluginJs.configs.recommended,
pluginRefresh.configs.recommended,
pluginReact.configs.flat.recommended,
...tseslint.configs.recommended,
{
plugins: {
'react-hooks': pluginHooks,
},
rules: {
'react/react-in-jsx-scope': 'off',
...pluginHooks.configs.recommended.rules,
},
},
]; |
The import reactPlugin from "eslint-plugin-react";
import tseslint from 'typescript-eslint';
import { type Linter } from "eslint";
const reactConfigRecommended = reactPlugin.configs.flat!.recommended
const tsEslintConfig = tseslint.config(
reactConfigRecommended,
);
// error: Argument of type ReactFlagConfig is not assignable to parameter of type InfiniteDepthConfigWithExtends
const linterConfig: Linter.Config[] = [
reactConfigRecommended,
}];
// error: Type ReactFlagConfig is not assignable to type Config<RulesRecord> |
@renchris |
Ah, okay, thanks. I'll look to raise the discussion issue there. |
FWIW, for anyone already using import { FlatCompat } from '@eslint/eslintrc';
import pluginJs from '@eslint/js';
import pluginReact from 'eslint-plugin-react';
import tseslint from 'typescript-eslint';
const compat = new FlatCompat();
/** @type {import('eslint').Linter.Config[]} */
export default [
{
files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'],
},
pluginJs.configs.recommended,
...tseslint.configs.recommended,
pluginReact.configs.flat.recommended,
...compat.extends('plugin:prettier/recommended'),
...compat.extends('plugin:react-hooks/recommended'),
{
rules: {
'no-debugger': 'warn',
'no-fallthrough': ['error', { commentPattern: 'break[\\s\\w]*omitted' }],
'react/react-in-jsx-scope': 'off',
'@typescript-eslint/no-unused-vars': ['warn'],
},
},
]; |
👋 Coming over from eslint/eslint#18093: ESLint is migrating to a new "flat config" format that will be the default in ESLint v9.
It doesn't look like
eslint-plugin-react-hooks
has documented support yet. But, based on searching around (e.g. vercel/next.js#49337), ESLint v9 is basically supported if you wire it up manually in your config:Most community plugins provide a more convenient wrapper. For example,
eslint-plugin-jsdoc
provides ajsdoc.configs['flat/recommended']
object:Would the React team be open to a PR adding in a preset object like that? And either way, updating the docs on https://www.npmjs.com/package/eslint-plugin-react-hooks?
Note: this was also filed as reactjs/react.dev#6430.
I'm posting this issue here as a reference & cross-linking it to the table in eslint/eslint#18093. If there's anything technical blocking the extension from working with flat configs, please let us know - we'd be happy to try to help! 💜
Additional resources:
(sorry for not using the issue templates - I wasn't sure whether this would count as a bug)
The text was updated successfully, but these errors were encountered: