refactor: render view-builder components as jsx elements instead of plain function calls (rules-of-hooks) (#4877)#4884
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR removes a React Rules-of-Hooks foot-gun in view-model builders by replacing C.Component({ ... }) plain function invocations with proper JSX element rendering (<C.Component ... />) across the affected builder modules, and renames those modules to .tsx to support JSX.
Changes:
- Converted 37
C.Component({ ... })builder call sites to JSX elements to ensure any hook-using builders execute hooks in their own component scope. - Updated builder-returned element types/props patterns (including
Buttonsarrays) to be valid JSX (e.g., addingkeyprops where elements are in an array literal). - Adjusted a returned component to be named to satisfy
react/display-namewhen returning a component type directly.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| app/viewModelBuilders/catalog/anvil-catalog/common/viewModelBuilders.tsx | Converts multiple builder component calls to JSX for consistent, hook-safe rendering in AnVIL catalog views. |
| app/viewModelBuilders/azul/lungmap/common/viewModelBuilders.tsx | Updates a FileNameCell builder call to JSX in the LungMAP builder. |
| app/viewModelBuilders/azul/hca-dcp/common/viewModelBuilders.tsx | Bulk conversion of builder calls to JSX, including hook-using BackPageHeroActions, plus JSX array keying and display-name adjustment. |
| app/viewModelBuilders/azul/hca-dcp/common/dataSummaryMapper/dataSummaryMapper.tsx | Converts a TypographyWordBreak builder call to JSX in the data summary mapper. |
Comments suppressed due to low confidence (1)
app/viewModelBuilders/azul/hca-dcp/common/viewModelBuilders.tsx:710
- Typo in the eslint-disable rationale comment:
NOOPRNERshould beNOOPENER(refers to thenoopenerpart ofrel="noopener noreferrer").
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
d1c80e7 to
7f18a63
Compare
NoopDog
approved these changes
Jul 1, 2026
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.
Summary
Closes #4877.
Converts every view-model builder call of the form
C.Component({...})(calling a component as a plain function) into<C.Component {...} />(rendering it as a JSX element). Calling a hook-using component as a plain function executes its hooks inside whatever renders the builder output (findable-ui'sComponentCreator) rather than in the component's own scope — a Rules of Hooks violation. The confirmed hook-using case isC.BackPageHeroActions(useConfig→useContext); the rest are hookless presentational builders converted uniformly so the foot-gun can't be silently reintroduced.JSX requires
.tsx, so the affected builder files were renamed viagit mv(history preserved).Changes
app/viewModelBuilders/azul/hca-dcp/common/viewModelBuilders.tsxapp/viewModelBuilders/catalog/anvil-catalog/common/viewModelBuilders.tsxapp/viewModelBuilders/azul/hca-dcp/common/dataSummaryMapper/dataSummaryMapper.tsxapp/viewModelBuilders/azul/lungmap/common/viewModelBuilders.tsxkeyprops to the elements inC.ButtonGroup'sButtonsarray (required once they are JSX elements in an array literal).getAnalysisPortalsKeyValueElTypeto satisfyreact/display-name(it returns a component directly rather than assigning it to a prop).Direct non-
C.builder calls (e.g.NTagCell({...})imported directly) were intentionally left as-is — they're outside the issue's scope.Verification
.tsbuilder files renamed to.tsxviagit mvC.Component({...})invocations rendered as<C.Component {...} />(all 37)next build --webpackgreen — hca-dcp, anvil-catalog, lungmap configsnpm run lint(0 errors),npx tsc(clean),npx prettier --check(clean) on changed files🤖 Generated with Claude Code