Skip to content

perf: FIT-1302: Fix non-deterministic React keys causing unnecessary remounts#9268

Open
bmartel wants to merge 1 commit intodevelopfrom
fb-fit-1302
Open

perf: FIT-1302: Fix non-deterministic React keys causing unnecessary remounts#9268
bmartel wants to merge 1 commit intodevelopfrom
fb-fit-1302

Conversation

@bmartel
Copy link
Contributor

@bmartel bmartel commented Jan 26, 2026

Problem

Two critical anti-patterns in React key usage:

  1. guidGenerator() as key - Creates a new key on every render, forcing React to completely unmount and remount the component. Found in App.jsx for RelationsOverlay.

  2. Array index as key - Causes incorrect diffing when items are added, removed, or reordered. Found in multiple components.

Solution

Replace non-deterministic keys with stable identifiers:

File Before After
App.jsx key={guidGenerator()} key="relations-overlay"
Grid.jsx key={i} key={selected.id}
SidePanels.tsx key={i} key={Component.displayName}
OutlinerTree.tsx key={idx} key={tag.name}
PolygonRegion.jsx key={item.id || guidGenerator()} key={item.id}
TextAreaRegionView.jsx key={idx} key={\${item.id}-line-${idx}`}`

Files Changed

  • web/libs/editor/src/components/App/App.jsx
  • web/libs/editor/src/components/App/Grid.jsx
  • web/libs/editor/src/components/SidePanels/SidePanels.tsx
  • web/libs/editor/src/components/SidePanels/OutlinerPanel/OutlinerTree.tsx
  • web/libs/editor/src/regions/PolygonRegion.jsx
  • web/libs/editor/src/tags/control/TextArea/TextAreaRegionView.jsx

Replace non-deterministic and index-based keys with stable identifiers
to improve React reconciliation performance.

Critical fixes:
- App.jsx: Replace guidGenerator() with stable 'relations-overlay' key
  (was causing RelationsOverlay to remount on every parent render)
- PolygonRegion.jsx: Remove guidGenerator() fallback, use item.id only

High-frequency component fixes:
- SidePanels.tsx: Use Component.displayName/name instead of index
- OutlinerTree.tsx: Use tag.name or tag.type instead of index
- Grid.jsx: Use selected.id instead of loop index
- TextAreaRegionView.jsx: Use item.id with line index for stability

Using array index as key causes React to incorrectly diff when items
are added, removed, or reordered. Using guidGenerator() creates a new
key every render, forcing complete remount of the component tree.
@codecov
Copy link

codecov bot commented Jan 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@netlify
Copy link

netlify bot commented Jan 26, 2026

Deploy Preview for heartex-docs canceled.

Name Link
🔨 Latest commit 18f260d
🔍 Latest deploy log https://app.netlify.com/projects/heartex-docs/deploys/6977b041aeb29f00081c9fa9

@netlify
Copy link

netlify bot commented Jan 26, 2026

Deploy Preview for label-studio-docs-new-theme canceled.

Name Link
🔨 Latest commit 18f260d
🔍 Latest deploy log https://app.netlify.com/projects/label-studio-docs-new-theme/deploys/6977b0417ddc0c0008958334

@netlify
Copy link

netlify bot commented Jan 26, 2026

Deploy Preview for label-studio-storybook ready!

Name Link
🔨 Latest commit 18f260d
🔍 Latest deploy log https://app.netlify.com/projects/label-studio-storybook/deploys/6977b0415b73530008a02c31
😎 Deploy Preview https://deploy-preview-9268--label-studio-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Jan 26, 2026

Deploy Preview for label-studio-playground ready!

Name Link
🔨 Latest commit 18f260d
🔍 Latest deploy log https://app.netlify.com/projects/label-studio-playground/deploys/6977b041f1bd000008efe622
😎 Deploy Preview https://deploy-preview-9268--label-studio-playground.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@robot-ci-heartex
Copy link
Collaborator

This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants