diff --git a/crates/oxc_linter/src/rules/react/exhaustive_deps.rs b/crates/oxc_linter/src/rules/react/exhaustive_deps.rs index 2eadb2a7bd4ca..831e2fad7e29a 100644 --- a/crates/oxc_linter/src/rules/react/exhaustive_deps.rs +++ b/crates/oxc_linter/src/rules/react/exhaustive_deps.rs @@ -525,7 +525,13 @@ impl Rule for ExhaustiveDeps { // for example if `props.foo`, AND `props.foo.bar.baz` was declared in the deps array // `props.foo.bar.baz` is unnecessary (already covered by `props.foo`) declared_dependencies.iter().tuple_combinations().for_each(|(a, b)| { - if a.contains(b) || b.contains(a) { + if a.contains(b) { + ctx.diagnostic(unnecessary_dependency_diagnostic( + hook_name, + &a.to_string(), + dependencies_node.span, + )); + } else if b.contains(a) { ctx.diagnostic(unnecessary_dependency_diagnostic( hook_name, &b.to_string(), @@ -2362,6 +2368,13 @@ fn test() { console.log(props.bar); }, [props, props.foo]); }", + r"function MyComponent(props) { + const local = {}; + useCallback(() => { + console.log(props.foo); + console.log(props.bar); + }, [props.foo, props]); + }", r"function MyComponent(props) { const local = {}; useCallback(() => { diff --git a/crates/oxc_linter/src/snapshots/react_exhaustive_deps.snap b/crates/oxc_linter/src/snapshots/react_exhaustive_deps.snap index 5dd874492a74b..a98f7f38d0677 100644 --- a/crates/oxc_linter/src/snapshots/react_exhaustive_deps.snap +++ b/crates/oxc_linter/src/snapshots/react_exhaustive_deps.snap @@ -514,7 +514,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Extract the expression to a separate variable so it can be statically checked. - ⚠ eslint-plugin-react(exhaustive-deps): React Hook useCallback has unnecessary dependency: props + ⚠ eslint-plugin-react(exhaustive-deps): React Hook useCallback has unnecessary dependency: props.foo ╭─[exhaustive_deps.tsx:6:14] 5 │ console.log(props.bar); 6 │ }, [props, props.foo]); @@ -523,6 +523,15 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Either include it or remove the dependency array. + ⚠ eslint-plugin-react(exhaustive-deps): React Hook useCallback has unnecessary dependency: props.foo + ╭─[exhaustive_deps.tsx:6:14] + 5 │ console.log(props.bar); + 6 │ }, [props.foo, props]); + · ────────────────── + 7 │ } + ╰──── + help: Either include it or remove the dependency array. + ⚠ eslint-plugin-react-hooks(exhaustive-deps): React Hook useCallback has missing dependencies: 'props.foo', and 'props.bar' ╭─[exhaustive_deps.tsx:6:14] 5 │ console.log(props.bar); @@ -559,7 +568,7 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Either include it or remove the dependency array. - ⚠ eslint-plugin-react(exhaustive-deps): React Hook useCallback has unnecessary dependency: local + ⚠ eslint-plugin-react(exhaustive-deps): React Hook useCallback has unnecessary dependency: local.id ╭─[exhaustive_deps.tsx:5:14] 4 │ console.log(local); 5 │ }, [local.id, local]);