@@ -47,7 +47,13 @@ export function useSlots<Config extends SlotConfig>(
4747 const keys = Object . keys ( config ) as Array < keyof Config >
4848 const values = Object . values ( config )
4949 const totalSlots = keys . length
50- let slotsFound = 0
50+
51+ // Pre-compute which slots use the [Component, testFn] matcher pattern
52+ // to avoid Array.isArray() checks in the hot inner loop
53+ const isArrayMatcher : boolean [ ] = new Array ( totalSlots )
54+ for ( let i = 0 ; i < totalSlots ; i ++ ) {
55+ isArrayMatcher [ i ] = Array . isArray ( values [ i ] )
56+ }
5157
5258 // eslint-disable-next-line github/array-foreach
5359 React . Children . forEach ( children , child => {
@@ -56,26 +62,16 @@ export function useSlots<Config extends SlotConfig>(
5662 return
5763 }
5864
59- // Short-circuit: if all slots are filled, remaining children go to rest
60- if ( slotsFound === totalSlots ) {
61- rest . push ( child )
62- return
63- }
64-
6565 let matchedIndex = - 1
6666 for ( let i = 0 ; i < totalSlots ; i ++ ) {
67- // Skip already-filled slots
68- if ( slots [ keys [ i ] ] !== undefined ) continue
69-
70- const value = values [ i ]
71- if ( Array . isArray ( value ) ) {
72- const [ component , testFn ] = value
67+ if ( isArrayMatcher [ i ] ) {
68+ const [ component , testFn ] = values [ i ] as ComponentAndPropsMatcher
7369 if ( ( child . type === component || isSlot ( child , component as SlotMarker ) ) && testFn ( child . props ) ) {
7470 matchedIndex = i
7571 break
7672 }
7773 } else {
78- if ( child . type === value || isSlot ( child , value as SlotMarker ) ) {
74+ if ( child . type === values [ i ] || isSlot ( child , values [ i ] as SlotMarker ) ) {
7975 matchedIndex = i
8076 break
8177 }
@@ -98,7 +94,6 @@ export function useSlots<Config extends SlotConfig>(
9894
9995 // If the child is a slot, add it to the `slots` object
10096 slots [ slotKey ] = child as SlotValue < Config , keyof Config >
101- slotsFound ++
10297 } )
10398
10499 return [ slots , rest ]
0 commit comments