Skip to content

perf(arrows): use reactive hooks for arrow handle display and editing state#8167

Merged
steveruizok merged 4 commits intomainfrom
sr/arrow-reactive-handles
Mar 5, 2026
Merged

perf(arrows): use reactive hooks for arrow handle display and editing state#8167
steveruizok merged 4 commits intomainfrom
sr/arrow-reactive-handles

Conversation

@steveruizok
Copy link
Copy Markdown
Collaborator

@steveruizok steveruizok commented Mar 5, 2026

Previously, any change to any shape would cause all arrows to render. We should be careful with any reactive call to getOnlySelectedShape, because it will call when the selected shape is changing. If we need to react to a change in which shape is selected, we should use getOnlySelectedShapeId.

In order to reduce unnecessary re-renders of arrow components, this PR changes a call to getOnlySelectedShape()?.id to getOnlySelectedShapeId.

To avoid an extra render when editing shape changes, it also wraps shouldDisplayHandles and isEditing checks in useValue hooks for finer-grained reactivity. It also refactors getArrowLabelPosition to accept isEditing as a parameter rather than computing it internally, avoiding redundant reactive lookups.

Change type

  • improvement

Test plan

  1. Create arrows between shapes
  2. Select an arrow — handles should display correctly
  3. Double-click an arrow label to edit — label positioning should work as before
  4. Deselect and verify handles disappear
  • Unit tests
  • End to end tests

Release notes

  • Improve arrow component rendering performance with finer-grained reactivity

Note

Medium Risk
Touches arrow rendering reactivity (selection/editing state and label positioning), so regressions could show up as missing handles or mispositioned labels, but the changes are localized to UI/perf code.

Overview
Reduces unnecessary arrow re-renders by switching arrow component state derivations to fine-grained useValue subscriptions (e.g. shouldDisplayHandles, selection, and editing state) and by preferring getOnlySelectedShapeId() over getOnlySelectedShape() where only the id is needed.

Refactors getArrowLabelPosition to accept an explicit isEditing flag and updates all call sites (geometry, component render, and SVG export) to avoid redundant reactive lookups when computing label bounds. Also updates touch-end handling in useCanvasEvents to use editor.getEditingShapeId().

Written by Cursor Bugbot for commit e04558e. This will update automatically on new commits. Configure here.

… state

Wrap shouldDisplayHandles and isEditing checks in useValue hooks for
finer-grained reactivity, avoiding unnecessary re-renders of arrow
components. Refactor getArrowLabelPosition to accept isEditing as a
parameter rather than computing it internally.
@huppy-bot huppy-bot bot added the improvement Product improvement label Mar 5, 2026
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
examples Ready Ready Preview Mar 5, 2026 10:18pm
5 Skipped Deployments
Project Deployment Actions Updated (UTC)
analytics Ignored Ignored Preview Mar 5, 2026 10:18pm
chat-template Ignored Ignored Preview Mar 5, 2026 10:18pm
tldraw-docs Ignored Ignored Preview Mar 5, 2026 10:18pm
tldraw-shader Ignored Ignored Preview Mar 5, 2026 10:18pm
workflow-template Ignored Ignored Preview Mar 5, 2026 10:18pm

Request Review

Replace editor.getOnlySelectedShape()?.id === shape.id with editor.getOnlySelectedShapeId() === shape.id in ArrowShapeUtil. This avoids fetching the full shape object and optional chaining, simplifying the null-check and improving readability/efficiency when verifying the selected shape.
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@steveruizok steveruizok added this pull request to the merge queue Mar 5, 2026
Merged via the queue into main with commit 6f8851f Mar 5, 2026
20 checks passed
@steveruizok steveruizok deleted the sr/arrow-reactive-handles branch March 5, 2026 22:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Product improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant