refactor(frontend): reduce NewRun prop syncing#13208
refactor(frontend): reduce NewRun prop syncing#13208google-oss-prow[bot] merged 1 commit intokubeflow:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors NewRunV2 to eliminate post-render effect-driven prop syncing by switching to keyed state initialization for pipeline, experiment, and pipeline version selection. The refactoring removes two useEffect blocks that were copying prop values into local state and replaces them with useKeyedState-based initialization that automatically resets state when the keyed prop identity changes.
Changes:
- Replaced effect-driven state syncing with keyed state initialization for
pipelineName,selectedExperiment, andpipelineVersionName - Derived
experimentIdandexperimentNamefromselectedExperimentinstead of maintaining separate state - Simplified the "Always use latest version" checkbox handler by removing manual state clearing (now automatic via key change)
- Added tests verifying rerender behavior when pipeline and experiment props change
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| frontend/src/pages/NewRunV2.tsx | Refactored state management to use keyed initialization, removing effect-driven syncing while maintaining correct behavior |
| frontend/src/pages/NewRunV2.test.tsx | Added tests to verify state updates when pipeline and experiment props change on rerender |
manaswinidas
left a comment
There was a problem hiding this comment.
Good refactoring — extends the existing useKeyedState pattern to replace two prop-mirroring effects. A few observations:
This is more than a refactor. The old experiment state was initialized with useState(chosenExperiment) but never re-synced when the chosenExperiment prop changed — only experimentName/experimentId were synced via the effect (which depended on local experiment, not the prop). That meant startRun could submit a stale experiment if chosenExperiment changed without user interaction. The keyed-state version fixes this. The new rerender tests correctly cover this previously-untested behavior.
Minor suggestions (non-blocking):
-
pipelineVersionNamekey expression — theuseLatestVersion ? \latest:${...}` : versionIdkey is clever (thelatest:` prefix prevents key collision), but it encodes toggle state into a key string in a way that's non-obvious. A one-line comment explaining the intent would help future readers. -
Test boilerplate — the two new tests manually spread all props instead of using the existing
buildNewRunV2Elementhelper (line ~225). Using it would cut ~20 lines per test:const { rerender } = render( <CommonTestWrapper> <NewRunV2 {...buildNewRunV2Element({ chosenExperiment: DEFAULT_EXPERIMENT })} /> </CommonTestWrapper>, );
-
handleExperimentChangebehavioral delta — the old code guardedsetExperimentNamebehindif (experiment.display_name), preserving a stale name if the new experiment lacked one. The new derivation (selectedExperiment?.display_name ?? '') shows empty instead. This is the better behavior, just noting it's a subtle change.
Overall LGTM — correctness looks solid, test coverage matches the behavioral change, and it removes two eslint-disable candidates.
|
There's a merge conflict |
Signed-off-by: Jeff Spahr <spahrj@gmail.com>
817c9a2 to
e838100
Compare
|
Addressed the review feedback on the rebased head
Focused verification on the rebased branch passed:
Result: formatter passed, |
|
/approve |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: zazulam The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Summary
NewRunV2Why
NewRunV2still had two non-toolbaruseEffectblocks whose only job was to copy pipeline, experiment, and version display data from props into local state after render. That pattern is the same effect misuse this cleanup series has been removing elsewhere: it adds post-render repair work, makes rerender behavior harder to reason about, and encouragesreact-hooks/exhaustive-depssuppressions.This PR keeps the slice narrow:
NewRunParametersV2is intentionally unchanged here, because its remaining mount-time propagation behavior still has a broader standalone-test contract and should be handled in its own follow-up if we keep goingWhat changed
NewRunV2now initializespipelineName,selectedExperiment, andpipelineVersionNamewithuseKeyedState(...)keyed from the corresponding prop identity instead of syncing them in effectsuseLatestVersion; blanking the displayed version name is derived from the keyed state initialization rather than an effect or imperative checkbox handler resetselectedExperimentNewRunV2.test.tsxnow verifies that rerendering with a different pipeline prop updates the displayed pipeline name, and rerendering with a different chosen experiment prop updates the displayed experiment nameVerification
cd frontend && fnm exec --using .nvmrc -- npx prettier@3.8.1 --check src/pages/NewRunV2.tsx src/pages/NewRunV2.test.tsxcd frontend && fnm exec --using .nvmrc -- npm run test:ui -- src/pages/NewRunV2.test.tsxcd frontend && fnm exec --using .nvmrc -- npm run typecheckResult: formatter passed,
src/pages/NewRunV2.test.tsxpassed with34tests, and typecheck passed.