Skip to content

[MIL-1550] fix useNavigation destructure false positive#481

Open
rayhanadev wants to merge 2 commits into
mainfrom
ray/da584aaa
Open

[MIL-1550] fix useNavigation destructure false positive#481
rayhanadev wants to merge 2 commits into
mainfrom
ray/da584aaa

Conversation

@rayhanadev
Copy link
Copy Markdown
Member

@rayhanadev rayhanadev commented May 25, 2026

Why?

react-compiler-destructure-method recommends destructuring methods from hook return values so React Compiler can reason about stable method references and dependencies more clearly. That guidance is still useful for ordinary hook objects, but it is not a safe recommendation for React Navigation's useNavigation() API.

React Navigation documents useNavigation as a hook imported from @react-navigation/native that returns the screen's navigation object, and its examples call methods as navigation.navigate(...) rather than destructuring the method first: https://reactnavigation.org/docs/use-navigation. The navigation object reference also describes navigate, goBack, dispatch, setOptions, and related APIs as methods on the navigation object, and notes that navigation functions such as navigate use dispatch behind the scenes: https://reactnavigation.org/docs/navigation-object.

The implementation matches that public contract: useNavigation returns the navigation object from React Navigation context (or the root navigation ref fallback), not an arbitrary plain hook-return object owned by userland code: https://github.com/react-navigation/react-navigation/blob/main/packages/core/src/useNavigation.tsx. Because the rule is a compiler-oriented hint, it should avoid suggesting a rewrite that diverges from React Navigation's documented object-method usage.

What changed?

  • Added a data-driven HOOK_IMPORT_SOURCES_WITH_UNSAFE_METHOD_DESTRUCTURING map so import-source carve-outs can be extended for future unsafe method-bearing hook APIs without adding bespoke rule branches.
  • Suppressed react-compiler-destructure-method only when the tracked hook is imported from a known unsafe source. Today that covers React Navigation's useNavigation from @react-navigation/native and @react-navigation/core.
  • Kept the existing React Compiler guidance for non-React-Navigation useNavigation() hooks, so similarly named userland hooks still report.
  • Documented why import-source carve-outs exist and why they must remain keyed by both hook name and module source.
  • Added regression tests covering @react-navigation/native, @react-navigation/core, and the custom-hook case that should still report.

Before:

import { useNavigation } from "@react-navigation/native";

const Screen = () => {
  const navigation = useNavigation();
  navigation.navigate("Chat", { sessionId });
};

The rule reported navigation.navigate(...) and suggested destructuring navigate.

After:

import { useNavigation } from "@react-navigation/native";

const Screen = () => {
  const navigation = useNavigation();
  navigation.navigate("Chat", { sessionId });
};

The React Navigation call is no longer reported, while custom/non-React-Navigation useNavigation() hooks still receive the destructuring recommendation.

Test plan

Users can verify correctness by running:

nr build && cd ../core && nr build && cd ../react-doctor && nr test tests/regressions/architecture-rules.test.ts

@reactreview
Copy link
Copy Markdown

reactreview Bot commented May 25, 2026

No new issues

Reviewed by reactreview for commit 1717270. Configure here.

@rayhanadev rayhanadev marked this pull request as ready for review May 25, 2026 18:05
Copilot AI review requested due to automatic review settings May 25, 2026 18:05
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the react-compiler-destructure-method architecture rule to avoid recommending method destructuring for React Navigation’s useNavigation() return value, since React Navigation’s documented API expects method calls off the navigation object (e.g. navigation.navigate(...)).

Changes:

  • Added an import-source keyed carve-out (HOOK_IMPORT_SOURCES_WITH_UNSAFE_METHOD_DESTRUCTURING) so specific hook/module combinations can opt out of method-destructuring advice.
  • Suppressed react-compiler-destructure-method hits for useNavigation when imported from @react-navigation/native or @react-navigation/core.
  • Added regression tests to ensure React Navigation is not flagged while similarly named non-RN hooks still are.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
packages/react-doctor/tests/regressions/architecture-rules.test.ts Adds regression coverage for React Navigation and custom useNavigation cases.
packages/oxlint-plugin-react-doctor/src/plugin/rules/architecture/react-compiler-destructure-method.ts Implements import-source-based suppression for unsafe hook-method destructuring (React Navigation).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 132 to 136
const allowedMethods = HOOK_OBJECTS_WITH_METHODS.get(hookSource);
if (!allowedMethods || !allowedMethods.has(methodName)) return;
if (isUnsafeMethodDestructureHookImport(node, hookSource)) return;

if (!isNodeOfType(node.parent, "CallExpression") || node.parent.callee !== node) return;
@rayhanadev rayhanadev changed the title fix useNavigation destructure false positive [MIL-1550] fix useNavigation destructure false positive May 25, 2026
@rayhanadev rayhanadev requested a review from aidenybai May 25, 2026 18:17
rayhanadev and others added 2 commits May 25, 2026 13:40
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants