Origin: adopted into #6270's scope by triage, then deferred out of PR #6591 by the dispatch order that PR received. Filed as its own card so the work survives #6270 closing — a card closing on Fixes # takes its deferred half with it (objectui#6584).
Blocked-by: #6270
What triage adopted (verbatim, comment 5414599274 on #6270)
The dev's related observation is adopted into scope as the sturdier half: re-key the load-bearing fetch effects onto the primitives they read (dataConfig.provider, dataConfig.object) so useMemo returns to being a pure optimisation; ⛔ the useRef/stable-key identity hack stays forbidden per the #6018 ruling.
Why PR #6591 did not do it
The dispatch order for #6270 forbade touching plugin-map or any downstream renderer's memo keys: that PR's job was to stop SchemaRenderer handing a fresh schema object to its children on every render, and widening it into consumers' effect deps would have made its reverse verification unreadable. The dev followed the order and flagged the conflict rather than silently picking a side. Not a defect in that PR — a deliberate deferral, recorded here.
Why it is still worth doing
PR #6591 makes the schema identity stable; it does not make it guaranteed. useMemo carries no semantic guarantee — React is permitted to discard a memo cache and recompute. So every fetch effect keyed on a memoised object identity is correct only for as long as that cache happens to survive: a discard re-runs the effect and refetches. Re-keying those effects onto the primitives they actually read removes the dependence on cache survival, and demotes useMemo back to what it is.
Two measurements from PR #6591 worth inheriting rather than re-deriving:
Constraints carried forward
File face
packages/plugin-map is the known member. The complete set is "every renderer whose fetch effect deps carry a memoised config object" — that census is the first step of this card, not an inherited claim, and it should be measured with a positive control before any zero in it is believed. packages/react/src/SchemaRenderer.tsx is expected to need no further change.
Origin: adopted into #6270's scope by triage, then deferred out of PR #6591 by the dispatch order that PR received. Filed as its own card so the work survives #6270 closing — a card closing on
Fixes #takes its deferred half with it (objectui#6584).Blocked-by: #6270
What triage adopted (verbatim, comment 5414599274 on #6270)
Why PR #6591 did not do it
The dispatch order for #6270 forbade touching
plugin-mapor any downstream renderer's memo keys: that PR's job was to stopSchemaRendererhanding a freshschemaobject to its children on every render, and widening it into consumers' effect deps would have made its reverse verification unreadable. The dev followed the order and flagged the conflict rather than silently picking a side. Not a defect in that PR — a deliberate deferral, recorded here.Why it is still worth doing
PR #6591 makes the schema identity stable; it does not make it guaranteed.
useMemocarries no semantic guarantee — React is permitted to discard a memo cache and recompute. So every fetch effect keyed on a memoised object identity is correct only for as long as that cache happens to survive: a discard re-runs the effect and refetches. Re-keying those effects onto the primitives they actually read removes the dependence on cache survival, and demotesuseMemoback to what it is.Two measurements from PR #6591 worth inheriting rather than re-deriving:
mapConfigwas keyed on[schema]byObjectMap's markeruseMemonever memoizes —getMapConfigruns unmemoized in the render body, somapConfighas a fresh identity every render #5976 (PR fix(plugin-map): memoize ObjectMap's mapConfig so the marker useMemo actually memoizes #6016,538ed9246, 2026-08-24);dataConfigbyObjectMap'sdataConfigpays aJSON.stringifyon every render to buy an identity that[schema]already gives for free #6018 (PR perf(plugin-map): key ObjectMap's dataConfig memo on [schema], not a per-render JSON.stringify #6266,2aa2c226a, 2026-08-25).SchemaRenderer's mount effect callsforceUpdate()once to re-check the component registry, so pre-fix(react): memoise the scoped-style schema SchemaRenderer hands down #6591 a scoped node handed its child two different schema objects on every mount — the churn never needed a parent re-render to fire.Constraints carried forward
useRef/ stable-key identity hack stays forbidden —ObjectMap'sdataConfigpays aJSON.stringifyon every render to buy an identity that[schema]already gives for free #6018's ruling.File face
packages/plugin-mapis the known member. The complete set is "every renderer whose fetch effect deps carry a memoised config object" — that census is the first step of this card, not an inherited claim, and it should be measured with a positive control before any zero in it is believed.packages/react/src/SchemaRenderer.tsxis expected to need no further change.