Skip to content

Conversation

@JounQin
Copy link
Member

@JounQin JounQin commented Jun 4, 2025

Summary by CodeRabbit

  • Chores

    • Enabled additional React and React Hooks linting rules and updated the codebase to address related issues.
    • Updated development dependencies to include the React Hooks ESLint plugin.
    • Enhanced ESLint configuration for improved React and TypeScript linting.
  • Refactor

    • Improved React hook dependency arrays throughout the codebase for more accurate effect and memoization behavior.
    • Refactored several components to optimize performance with React hooks such as useMemo and useCallback.
    • Simplified and centralized resource mapping logic in the permissions table component.
    • Updated the Tabs component to a plain functional component with improved prop handling.
  • Style

    • Made minor formatting adjustments for consistent code style and spacing in UI elements.
  • Bug Fixes

    • Improved key assignment in list rendering to reduce React warnings.

@JounQin JounQin self-assigned this Jun 4, 2025
Copilot AI review requested due to automatic review settings June 4, 2025 08:56
@changeset-bot
Copy link

changeset-bot bot commented Jun 4, 2025

🦋 Changeset detected

Latest commit: 23dd206

The changes in this PR will be included in the next version bump.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Jun 4, 2025

Walkthrough

This change enables and configures React and React Hooks ESLint plugins, updating the codebase to address all resulting lint issues. It adjusts dependency arrays in React hooks, improves memoization, and refactors several components for better lint compliance. The ESLint configuration and dependencies are updated accordingly, with no changes to public APIs.

Changes

File(s) Change Summary
.changeset/quick-zoos-allow.md Added changeset documenting the ESLint plugin enablement and codebase fixes.
eslint.config.js Enhanced ESLint config: added React and React Hooks plugins and related recommended configs.
package.json Added eslint-plugin-react-hooks to devDependencies.
src/global/SiteOverrides/index.tsx
src/global/VersionsNav/index.tsx
Expanded React hook dependency arrays to include all relevant variables.
src/runtime/components/ExternalSiteLink.tsx
src/runtime/components/_ExternalSiteBase.tsx
Updated useMemo dependencies to reflect dynamic inputs.
src/runtime/components/K8sCrd.tsx
src/runtime/components/OpenAPIPath.tsx
Updated hook dependencies and added explicit spaces in JSX for consistent rendering.
src/runtime/components/K8sPermissionTable.tsx Refactored mapping logic, centralized resource mapping, and improved memoization.
src/runtime/components/Mermaid.tsx Added id to the useEffect dependency array.
src/runtime/components/OpenAPIRef.tsx Improved React key usage, adjusted memoization dependencies, and updated ref collection logic.
src/runtime/components/Overview.tsx Refactored with useCallback and useMemo for internal functions and computations.
src/runtime/components/Tabs.tsx Refactored from forwardRef to plain functional component with direct ref prop.
src/runtime/components/TermsTable.tsx Added ESLint directive to suppress array index key warning.
src/runtime/components/_HeadingTitle.tsx Adjusted useMemo dependencies and added ESLint disable comment.
src/runtime/hooks/useIsPrint.ts
src/runtime/hooks/useSiteOverrides.ts
Expanded useEffect dependency arrays for correct hook behavior.

Sequence Diagram(s)

sequenceDiagram
  participant Dev as Developer
  participant ESLint as ESLint Config
  participant Code as Codebase

  Dev->>ESLint: Add React and Hooks plugins
  Dev->>Code: Update hook dependency arrays and memoization
  ESLint->>Code: Lint with new rules
  Code-->>Dev: Reports issues
  Dev->>Code: Fixes all reported lint issues
  Code-->>ESLint: Passes linting
Loading

Possibly related PRs

  • alauda/doom#58: Also modifies src/runtime/components/_HeadingTitle.tsx, focusing on memoization and dependency arrays related to slug computation, indicating a direct code-level relation.

Suggested labels

bug

Poem

🐇
The linting winds have blown anew,
With hooks and rules both fresh and true.
Arrays expanded, memos tight,
Each warning chased into the night.
React and TypeScript now aligned,
A codebase tidy, well-refined!
🌱✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@JounQin JounQin changed the title chore: enable eslint-plugin-react-hooks chore: enable eslint-plugin-react-hooks and @eslint-react/eslint-plugin Jun 4, 2025
@pkg-pr-new
Copy link

pkg-pr-new bot commented Jun 4, 2025

Open in StackBlitz

npm i https://pkg.pr.new/@alauda/doom@60

commit: 121c653

Signed-off-by: JounQin <admin@1stg.me>
Copy link
Contributor

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 integrates eslint-plugin-react-hooks and addresses hook dependency issues across the codebase.

  • Added and configured eslint-plugin-react-hooks with recommended rules.
  • Updated dependency arrays in various React hooks (useEffect, useMemo, useCallback).
  • Minor JSX adjustments for list keys and ref forwarding.

Reviewed Changes

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

Show a summary per file
File Description
package.json Added eslint-plugin-react-hooks to dependencies
eslint.config.js Enabled React Hooks lint rules
src/runtime/hooks/useSiteOverrides.ts Added missing dependencies to useEffect
src/runtime/components/Tabs.tsx Refactored Tabs component; addressed ref forwarding
src/runtime/components/TermsTable.tsx List items keyed by index; consider unique keys
src/runtime/components/OpenAPIPath.tsx Removed unused dependency from hook dependency array
Comments suppressed due to low confidence (3)

src/runtime/components/Tabs.tsx:9

  • Using ref as a prop in a functional component does not forward React refs. You should wrap the component in forwardRef or accept a prop like innerRef and pass it to the DOM node.
export const Tabs = ({ ref, children, ...props }: TabsProps) => {

src/runtime/components/TermsTable.tsx:21

  • [nitpick] Using the array index as a key can cause rendering issues when the list changes. Consider using a unique identifier from item or the item value itself as the key.
// eslint-disable-next-line @eslint-react/no-array-index-key

src/runtime/components/OpenAPIPath.tsx:207

  • [nitpick] The page.routePath dependency isn’t used inside this memoized function. Removing it will avoid unnecessary recalculations.
  }, [openapiPath_, page.routePath, path])

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/runtime/components/K8sCrd.tsx (1)

45-46: Consider alternatives to direct state setting in useEffect.

While the ESLint disable comment shows awareness of the issue, direct state setting in useEffect can cause unnecessary re-renders. Consider using a ref or restructuring the logic to avoid this pattern.

Alternative approach:

-  useEffect(() => {
-    // eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect
-    setOpen(expandAll)
-  }, [expandAll])
+  useEffect(() => {
+    setOpen((prev) => expandAll !== prev ? expandAll : prev)
+  }, [expandAll])
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 50fd4cb and 23dd206.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (18)
  • .changeset/quick-zoos-allow.md (1 hunks)
  • eslint.config.js (2 hunks)
  • package.json (1 hunks)
  • src/global/SiteOverrides/index.tsx (1 hunks)
  • src/global/VersionsNav/index.tsx (2 hunks)
  • src/runtime/components/ExternalSiteLink.tsx (1 hunks)
  • src/runtime/components/K8sCrd.tsx (5 hunks)
  • src/runtime/components/K8sPermissionTable.tsx (1 hunks)
  • src/runtime/components/Mermaid.tsx (1 hunks)
  • src/runtime/components/OpenAPIPath.tsx (2 hunks)
  • src/runtime/components/OpenAPIRef.tsx (3 hunks)
  • src/runtime/components/Overview.tsx (4 hunks)
  • src/runtime/components/Tabs.tsx (2 hunks)
  • src/runtime/components/TermsTable.tsx (1 hunks)
  • src/runtime/components/_ExternalSiteBase.tsx (1 hunks)
  • src/runtime/components/_HeadingTitle.tsx (2 hunks)
  • src/runtime/hooks/useIsPrint.ts (1 hunks)
  • src/runtime/hooks/useSiteOverrides.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (6)
src/runtime/components/_ExternalSiteBase.tsx (1)
src/runtime/hooks/useTranslation.ts (1)
  • useLang (7-7)
src/runtime/components/K8sCrd.tsx (1)
src/runtime/components/Badge.ts (2)
  • Badge (1-1)
  • Badge (1-1)
src/runtime/components/OpenAPIPath.tsx (2)
src/runtime/components/_X.tsx (1)
  • X (3-3)
src/runtime/components/_Markdown.tsx (1)
  • Markdown (7-16)
src/runtime/components/OpenAPIRef.tsx (1)
src/runtime/components/_X.tsx (1)
  • X (3-3)
src/runtime/components/Tabs.tsx (1)
src/runtime/hooks/useIsPrint.ts (1)
  • useIsPrint (40-44)
src/runtime/components/K8sPermissionTable.tsx (1)
src/plugins/permission/types.ts (1)
  • FunctionResource (3-8)
🪛 ESLint
src/runtime/components/Tabs.tsx

[error] 2-2: Unable to resolve path to module 'react'.

(import-x/no-unresolved)

src/runtime/components/Overview.tsx

[error] 14-14: Unable to resolve path to module 'react'.

(import-x/no-unresolved)

🔇 Additional comments (36)
package.json (1)

124-124: LGTM! Correctly adds React Hooks ESLint plugin.

The addition of eslint-plugin-react-hooks aligns perfectly with the PR objective to enable React Hooks linting rules.

src/runtime/components/K8sCrd.tsx (2)

77-88: Good improvement to JSX spacing consistency.

The explicit space fragments ensure consistent visual spacing between elements, improving UI consistency.


184-184: Critical fix: Corrected useMemo dependency array.

This is an important correction - the memoized value depends on both crdPath and name, but the dependency array was empty. This fix prevents stale closures and ensures proper memoization behavior.

src/runtime/components/ExternalSiteLink.tsx (1)

34-37: Excellent fix: Corrected missing useMemo dependency.

The memoized site value depends on the name prop, so including it in the dependency array ensures the memoization works correctly when name changes. This prevents stale values and potential bugs.

src/runtime/components/TermsTable.tsx (1)

21-22: Verify if a better unique key is available.

While using array indices as keys is generally discouraged, it may be acceptable here if the list is static and order doesn't change. However, consider if the item string itself could serve as a unique key, or if there's other identifying information available.

Alternative approach if items are unique:

-          // eslint-disable-next-line @eslint-react/no-array-index-key
-          <X.li key={index}>{item}</X.li>
+          <X.li key={item}>{item}</X.li>
src/runtime/hooks/useIsPrint.ts (1)

35-35: LGTM: Correct dependency array fix for exhaustive-deps compliance.

The addition of onChange to the dependency array is correct since the effect uses this callback. This ensures the event listener is properly updated if the onChange function identity changes, aligning with React hooks best practices.

.changeset/quick-zoos-allow.md (1)

1-6: LGTM: Well-documented changeset.

The changeset properly documents the patch update for enabling React hooks ESLint plugins and related fixes.

src/global/SiteOverrides/index.tsx (1)

74-81: LGTM: Comprehensive dependency array fix.

The expanded dependency array correctly includes all variables used within the effect (articleTitle, frontmatter.title, frontmatter.titleSuffix, pageType, siteData, title). This ensures the document title updates properly when any of these values change, which is the intended behavior.

src/runtime/hooks/useSiteOverrides.ts (1)

128-128:

Details

✅ Verification successful

Verify the behavioral impact of this dependency array change.

While adding acpSite and siteData.base to the dependency array aligns with exhaustive-deps rules, this changes the effect from running once on mount to re-running whenever these values change. Given the global state management with normalizedSiteOverrides and promise, please verify this doesn't cause unintended side effects like multiple concurrent fetches.

The early return check if (normalizedSiteOverrides) should prevent redundant fetches, but please test that the global state behaves correctly when the effect re-runs.


🏁 Script executed:

#!/bin/bash
# Description: Check if there are other places that rely on the one-time fetch behavior

# Search for usages of normalizedSiteOverrides and promise variables
rg -A 3 -B 3 "normalizedSiteOverrides|promise.*=" src/

# Look for other effects or functions that might expect single initialization
ast-grep --pattern 'useEffect($_, [])'

Length of output: 2826


Effect dependencies update verified

  • A search found no other useEffect(..., []) hooks that would rely on a strictly one-time fetch.
  • The global normalizedSiteOverrides and promise guard ensures the fetch only ever runs once, even if the effect re-fires.
  • Adding [acpSite, siteData.base] to the dependency array does not introduce redundant or concurrent fetches.

No further changes required.

src/global/VersionsNav/index.tsx (2)

109-109: Correct dependency array fix for React Hooks ESLint rule.

Adding version and versionsBase to the dependency array is correct since both variables are used within the effect logic.


123-123: ESLint disable comment is appropriately used.

The disable comment for @eslint-react/hooks-extra/no-direct-set-state-in-use-effect is justified here since you're performing a direct comparison and conditional state update, which is a valid pattern in this mutation observer context.

src/runtime/components/Mermaid.tsx (1)

35-35: Correct dependency array fix for React Hooks ESLint rule.

Adding id to the dependency array is correct since the id variable is used in the mermaid.render call within the effect (line 25). This ensures the diagram re-renders when the component ID changes.

src/runtime/components/_ExternalSiteBase.tsx (2)

97-100: Correct dependency array fix for useMemo.

Adding name to the dependency array is correct since the name variable is used in the find operation to locate the site.


106-106: Correct dependency array fix for useMemo.

The dependency array [lang, name, site?.displayName] correctly includes all variables used in the computation: lang for language selection, name for the fallback uppercase transformation, and site?.displayName for the primary display name source.

src/runtime/components/_HeadingTitle.tsx (3)

24-24: Correct optimization of useMemo dependency array.

Removing X from the dependency array is correct since HeadingComponents is a static array and X is a constant import that never changes.


28-28: Appropriate ESLint disable comment.

The disable comment for @eslint-react/no-children-to-array is justified here since Children.toArray is necessary to extract string content from the children for slug generation.


39-39: Correct dependency array fix for useMemo.

Adding slugger to the dependency array is correct since it's used in the computation via slugger?.slug(slugFromChildren) on line 36.

src/runtime/components/OpenAPIPath.tsx (2)

56-69: Good fix for React Hooks dependency array, but consider the spacing pattern.

The useMemo dependency array fix on line 207 is excellent - it properly includes all dependencies that could change (openapiPath_, page.routePath, path), preventing stale closures.

The explicit fragment wrapping for spacing around <Badge> and <Markdown> components is functional but creates verbose JSX. Consider if CSS margins would be cleaner.


207-207: Critical React Hooks dependency fix applied correctly.

This change fixes a significant React Hooks issue where the useMemo hook was missing dependencies, which could lead to stale closures and incorrect memoization behavior.

eslint.config.js (3)

4-4: ESLint plugin imports are correct.

Proper imports for both React and React Hooks ESLint plugins.

Also applies to: 7-7


17-18: Good choice of React ESLint configurations.

Using react.configs.recommended and reactHooks.configs['recommended-latest'] follows current best practices. The "recommended-latest" config for React Hooks includes the most up-to-date rules.


21-25: Proper TypeScript-specific React configuration.

Adding react.configs['recommended-type-checked'] for TypeScript files provides enhanced type-aware React linting, which is valuable for catching React-specific TypeScript issues.

src/runtime/components/OpenAPIRef.tsx (3)

108-109: Excellent improvement to React key usage.

Changing from array index to property name as the React key is a significant improvement. Using property names provides stable, unique keys that won't cause React reconciliation issues when the order changes.


175-175: Critical useMemo dependency array fix.

This fixes a serious React Hooks issue where the memoization was missing dependencies, potentially causing stale closures and incorrect behavior when openapiPath_ or schema changed.


178-178: Smart defensive programming.

Adding the openapi check prevents the refs collection from running when the OpenAPI document isn't available, avoiding potential runtime errors.

src/runtime/components/Tabs.tsx (3)

6-7: Clean TypeScript typing for the refactored component.

The TabsProps type alias properly combines the original component props with RefAttributes<HTMLDivElement>, maintaining type safety after removing forwardRef.


9-9: Valid forwardRef to direct ref refactoring.

The change from forwardRef to direct ref prop handling is correct and simpler. The ref is properly passed to the wrapping div element.

Also applies to: 12-12


14-17: Appropriate ESLint disables for print mode rendering.

The ESLint disables are justified here:

  • @eslint-react/no-children-map: Using Children.map is necessary for the print mode transformation
  • @eslint-react/no-array-index-key: Using array index as key is acceptable in print mode where the list is static and won't be reordered
src/runtime/components/Overview.tsx (6)

32-42: Excellent extraction of pure function.

Moving getChildLink outside the component scope prevents unnecessary recreations on each render and improves performance. The function is pure and doesn't depend on any component state or props.


60-67: Correct memoization of filter function.

The useCallback wrapper with [routePath] dependency is appropriate since subFilter depends on routePath for its closure behavior.


71-74: Proper memoization of computed array.

The useMemo with dependencies [pages, subFilter] correctly identifies the values that affect the computation. This prevents unnecessary re-filtering when other component state changes.


89-126: Well-structured memoization with comprehensive dependencies.

The useCallback wrapper correctly identifies all dependencies: overviewModules, props.overviewHeaders, and routePath. The function signature and logic remain unchanged while optimizing for re-renders.


133-184: Appropriate callback memoization for complex function.

The dependency array [frontmatter, normalizeSidebarItem, subFilter] correctly captures all the values used within the function. This memoization will prevent unnecessary re-computations when other component dependencies change.


186-201: Effective memoization of expensive computation.

The useMemo with [getGroup, overviewSidebarGroups] dependencies is well-placed for this complex computation that involves multiple iterations and filtering operations.

src/runtime/components/K8sPermissionTable.tsx (2)

87-96: Excellent performance optimization by extracting expensive computation.

Moving the allFunctionResources computation to module level prevents this expensive reduce operation from running on every component render. The logic remains identical while significantly improving performance.


99-111: Proper memoization with justified ESLint disable.

The useMemo correctly depends only on functions since allFunctionResources is now a module-level constant. The ESLint disable comment for exhaustive-deps is justified because including allFunctionResources in the dependency array would be unnecessary and could cause ESLint confusion since it's a constant.

@JounQin JounQin merged commit ab03ec5 into main Jun 4, 2025
22 of 24 checks passed
@JounQin JounQin deleted the chore/eslint branch June 4, 2025 09:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants