A memoised component skips re-rendering when its props are shallowly equal, and an inline object or array literal is a new reference on every parent render.
// memo does nothing: style and items are new every time
<Row style={{ padding: 8 }} items={rows.filter(Boolean)} />
// so hoist, or memoise, or the wrapper is pure cost
const style = { padding: 8 };
const items = useMemo(() => rows.filter(Boolean), [rows]);
The wrapper is not free — it adds a comparison per render and a slot of memory per instance — so applying it broadly to a tree that re-renders anyway makes things slower. The honest workflow is to profile first with the React DevTools profiler, find the component that is genuinely expensive, and memoise that one. A custom comparison function is available and is almost always a sign that the props want restructuring instead.