Repository navigation
fix(react-virtual): position directDomUpdates rows that mount without the owner - #1301
Conversation
… the owner A row mounted by a child that re-renders on its own (local state, context, a resolved Suspense boundary) never reached the owner's applyDirectStyles layout effect, and a fixed-size row raises no onChange when measured, so it stayed unpositioned until the range changed. Position rows as they register through measureElement, and let containerRef position the rows that mounted together with the container, since their refs attach before its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: e83d3c3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
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 |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (3)
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughThe React adapter now positions virtual rows during measurement registration and when a container attaches. Tests cover rows revealed by an independent child update and rows mounted with the container. ChangesDirect DOM row positioning
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix Merge Risk: ⚪ Minimal · up to No merge-blocking issue was identified in the row-positioning change. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)✅ Passed checks (4 passed)Full details: Docstring CoverageExplanation Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 2 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Some tools did not complete. Review the errors below. 🔧 ESLint
packages/react-virtual/tests/index.test.tsxParsing error: "parserOptions.project" has been provided for 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 |
|
View your CI Pipeline Execution ↗ for commit e83d3c3
☁️ Nx Cloud last updated this comment at |
…irtualizerState The positioning fix itself landed in TanStack#1301. These tests cover the case the hook makes common: a memoised child rendering rows through `useVirtualizerState` commits on its own when the owner, or anything in its render pass, has already read the new range. `_willUpdate` then publishes to the child without an `onChange`, the owner does not render again, and the child's rows mount after the owner's layout effect has run. Also pins `onChange` in the `_willUpdate` publish tests: it fires once, before the listener, for a range change, and not at all when only the total size changes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
With
directDomUpdates, rows were positioned only by the owner's layout effect or by the nextonChange. A row mounted by a child that re-renders on its own (local state, context, a resolved Suspense boundary) commits without the owner, so that effect never runs. A fixed-size row raises noonChangewhen measured either, so the row stays unpositioned until the range changes.Rows are now positioned as they register:
applyItemPositionis the per-row write pulled out ofapplyDirectStyles. It is unchanged and stays idempotent throughlastPositions.Extracted from #1296:
useVirtualizerStatemakes this case common because it lets a memoised child render rows on its own, but the bug exists without it.Evidence
Two new tests in
packages/react-virtual/tests/index.test.tsx. Both use fixed 50px rows anddirectDomUpdates:main): both fail. Row 1 is positioned, but the rows the child mounts later have notransform.Also run for react-virtual:
test:types,test:eslint,build, and the full e2e suite (36 passed).Merge Danger
Door: two-way
No API change. The fix only adds position writes in places that skipped them before, and reverting it is a plain revert.
Blast Radius:
directDomUpdatesOnly affects
directDomUpdates: true. A row can now get its position one step earlier, from its own ref callback instead of the owner's layout effect. The value written is the same, andlastPositionsstops the effect from writing it twice.✅ Checklist
pnpm run test:pr. (I ran the affected react-virtual targets listed above instead.)🚀 Release Impact
🤖 Generated with Claude Code
Summary by CodeRabbit