Skip to content

ObjectView's non-grid fetch re-runs once per parent render when the host passes an inline views array — measured 4 queries where a stable array gives 1 #6460

Description

@claude

Surfaced and measured while implementing objectui#6419 (the $expand gate on the same effect). Filed separately: same effect, different defect — this is re-run churn, not expansion — and objectui#6419's fix neither causes nor removes it.

The defect

ObjectView's non-grid fetch effect lists activeView among its dependencies:

packages/plugin-view/src/ObjectView.tsx
const activeView = viewsPropResolved?.find(v => v.id === currentActiveViewId) || viewsPropResolved?.[0];
...
}, [schema.objectName, dataSource, currentViewType, refreshKey,
currentNamedViewConfig, activeView, renderListView, ...]);

activeView is an element of the views prop array. A host that builds that array inline — views={[{ id: 'cal', type: 'calendar', label: … }]} — produces a fresh element object on every one of its own renders, so activeView is a new reference every render and the effect re-runs, issuing a new find() each time.

The effect only ever reads activeView?.filter and activeView?.type (the latter via currentViewType, which is already its own dependency), so the identity of the object is not what it needs.

Measured

Instrumented adapter (getObjectSchema and find both resolving in 30ms), a parent that re-renders three times on a 20ms timer, defaultViewType: 'calendar':

FRESH `views` array each parent render find calls: 4
STABLE `views` array (control) find calls: 1

Same harness, same parent, the only difference being whether the array literal is hoisted. The control is what makes this a defect rather than a property of re-rendering: a parent that re-renders with a stable array issues one query.

After objectui#6419's gate the churning count is 3 rather than 4 (every run now happens after the schema resolution settles, so the pre-resolution run no longer queries) — better, but still one query per parent render.

Why it matters beyond the query count

ObjectView hands its rows to the child view as data={data}, which suppresses the child's own fetch. Each extra find() therefore also re-delivers a fresh row array downstream — the "duplicate events in child views like the calendar" hazard, from a different direction than objectui#6419's.

Not folded into objectui#6419

Deliberately: different defect class, and the fix has a real design choice in it that the expansion card did not — depend on the fields the effect reads (activeView?.id plus whatever filter identity is needed) rather than the object, or ask hosts for a stable array, or memoize on a derived key. That choice wants its own triage rather than riding along.

Generated by Claude Code


Generated by Claude Code

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatched

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions