Skip to content

RFC: useContextSelector() amend with Option D (Relay pattern)#36001

Open
layershifter wants to merge 5 commits intomasterfrom
layershifter/rfc-context-selector-option-d
Open

RFC: useContextSelector() amend with Option D (Relay pattern)#36001
layershifter wants to merge 5 commits intomasterfrom
layershifter/rfc-context-selector-option-d

Conversation

@layershifter
Copy link
Copy Markdown
Member

@layershifter layershifter commented Apr 18, 2026

Summary

The original RFC considered Options A, B, C and selected A ("do nothing"). Option D was not considered at the time - it emerged from a conversation with the React team after the decision was made. Option D strictly improves on Option A for the "Glitchy Behavior" case without regressing anything else.

What's in the addendum

  1. New root-cause analysis of the "Glitchy Behavior" note the original RFC flagged but didn't bottom out. The issue is a fiber.lanes pollution issue in React's dispatchSetStateInternal eager-bailout check - the bound-at-mount fiber becomes the stale alternate after the first listener-driven commit and its lanes never get cleared, permanently failing the NoLanes precondition.
  2. Empirical confirmation via patched react-dom.development.js that logs fiber.lanes / alternate.lanes at the check site. First dispatch: fiber=0 alt=0 eager=TRUE. All subsequent dispatches on that fiber: fiber=1 alt=0 eager=FALSE.
  3. Option D specification: read valueRef.current during render (like useSyncExternalStore.getSnapshot), no [value, selected] state tuple, no setState(prev => prev) bailout trick. Listener compares selector(newValue) against a layout-effect-latched lastReturnedRef.current and force-updates only when the slice actually differs. Matches Relay's useFragmentInternal_CURRENT.js pattern.

Accompanying PR

#36002 — implementation of Option D in @fluentui/react-context-selector.

Out of scope

  • Level 1 tearing. Unchanged from original RFC.
  • Any API changes. Option D is API-compatible.

The original RFC considered Options A, B, C and selected A (do nothing).
Option D was not considered at the time — it emerged from a conversation
with the React team after the decision was made.

This addendum:
- Documents the root cause of the original RFC's "Glitchy Behavior" note:
  fiber.lanes pollution on the bound-at-mount fiber in
  dispatchSetStateInternal's eager-bailout check.
- Specifies Option D: allow Level 1 tearing, heal in effect via
  epoch/selector check. Matches Relay's useFragmentInternal pattern.
- Compares Option D to Option A across glitch, tearing, concurrent
  correctness, lint, and API dimensions.
- Re-establishes why Options B and C remain inadequate, with new empirical
  evidence against C (uncommitted-transition value leaks to urgent sibling
  renders under concurrent mode).
- Includes measurements from an investigation probe.

Does not modify the original decision record. The addendum is clearly dated
and labeled so the history of the prior decision is preserved.

Accompanying implementation PR: layershifter/fix-context-selector-bailout.
@github-actions github-actions Bot added the Type: RFC Request for Feedback label Apr 18, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 18, 2026

📊 Bundle size report

✅ No changes found

@github-actions
Copy link
Copy Markdown

Pull request demo site: URL

…nk public repro

- Drop references to docs/phase-3-root-cause.md, docs/phase-5-comparison.md,
  and repro/tests/list-probe-cycling.json (private investigation workspace).
- Replace with link to public reproduction repo:
  https://github.com/layershifter/context-selector-bailout-repro
- Pin Relay implementation references to commit e3c9d1b5661fb6f58e4d58f81cd930e09a47a89a
  so links don't move as main progresses.
@layershifter layershifter changed the title docs(rfc): amend context-selector-tearing with Option D (Relay pattern) rfc: useContextSelector() amend with Option D (Relay pattern) Apr 20, 2026
@layershifter layershifter marked this pull request as ready for review April 20, 2026 08:45
@layershifter layershifter requested review from a team as code owners April 20, 2026 08:45
@layershifter layershifter force-pushed the layershifter/rfc-context-selector-option-d branch from b0d9e7a to 487dd27 Compare April 20, 2026 08:50
@layershifter layershifter changed the title rfc: useContextSelector() amend with Option D (Relay pattern) RFC: useContextSelector() amend with Option D (Relay pattern) Apr 20, 2026
Copy link
Copy Markdown
Contributor

@Hotell Hotell left a comment

Choose a reason for hiding this comment

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

the PR with implementation was already merged so not sure why this is titled as RFC when it's "documentation" improvement. ty

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

Labels

Type: RFC Request for Feedback

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants