Repository navigation
Conversation
React writes a controlled control's value and checked state back after its change handlers run. Redact only synced them on re-render, so a handler that rejected an edit by not calling setState left the typed text, checkbox toggle, radio selection or select choice in the DOM. The restore runs after the element's last Redact listener for the native input or change event, so onChange, onInput and their capture forms all read the edit, also with real user input, which runs microtasks between listeners. It is queued behind the handler's own updates (microtask, or act's queue), so it reads the props they render and keeps the caret of an accepted edit. Hydration records the props too, and a radio restores the rest of its group. Fixes TanStack#115. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
These controls fire input before change. With onInput and onChange both set, the restore ran after the input listener, and since real clicks run microtasks between events, onChange read the restored state instead of the click. A change listener now owns the restore for them; an onInput alone still restores after input. Refs TanStack#115. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The restore ran in a microtask after the control's last Redact listener, and real input runs microtasks between listeners. So an ancestor's onInput or a later native listener read the restored value, and an ancestor that accepted the edit lost it. A capture listener that stopped propagation also skipped the restore: the target's bubble listener, which owned it, never ran. The control's listeners now mark the native event, and listeners on the root and portal containers restore once it reaches them, as React's root listener does. A stopped or non-bubbling event restores at once, since it never reaches a container. Listening on the container rather than the document keeps the restore when a native listener on the container stops propagation, and covers shadow roots. A checkbox, radio or select with a change listener still restores after change; with only onInput it restores after input. Refs TanStack#115. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
React restores a controlled control after any change event, whether or not it has handlers, so a control with value or checked and no onChange stays read-only. Redact only marked the event for a restore from its own listeners on the control. A handler-less controlled input stayed editable, and clicking a controlled radio without onChange changed its group even when its siblings had one. Recording a control's props now adds one shared listener that marks the event like a handler does, once the control is controlled, so uncontrolled controls pay nothing. The container listeners from TanStack#116 then restore it after every listener has run. Redact has no dev warning for value without onChange; this adds none. Refs TanStack#115. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: cd5644a The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
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. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #115. Stacked on #116; this covers its first two "Not covered" items. Until #116 merges, this diff includes its commits; review only the last one (
cd5644a).React restores after every change event, handler or not (
createAndAccumulateChangeEventcallsenqueueStateRestore), so a controlled control withoutonChangestays read-only and a click on a handler-less radio restores its group. #116 only marked the event for a restore from Redact listeners on the control, so both kept the edit.What changes
checkedfor checkbox and radio,valueotherwise), recording its props adds one shared listener that marks the event as a handler does, also on hydration. fix: restore controlled form controls after onChange #116's container listeners then restore it. Uncontrolled controls get none.valuewithoutonChangehas no Redact counterpart; this adds none.Size
+12 to +57 B gzip against #116; two entries go over budget.
UNHANDLED_RESTORE_SIZE_ALLOWANCEholds the measured increments and needs your approval.Not covered
Testing
On #116 the 7 new jsdom tests for handler-less controls fail, as do the handler-less input and radio browser tests; an eighth jsdom test guards against restoring uncontrolled inputs. Browser results hold in Chromium, Firefox and WebKit, and
pnpm test:prpasses on Node 24.22.0.I used Claude Code to write the fix and tests, and had it run the suites and a separate review pass.