@@ -143,6 +143,16 @@ export class ReactRouterViewStack extends ViewStacks {
143143 // Special case: reuse tabs/* and other specific wildcard routes
144144 // Don't reuse index routes (empty path) or generic catch-all wildcards (*)
145145 if ( existingPath === routePath && existingPath !== '' && existingPath !== '*' ) {
146+ // For parameterized routes (containing :param), only reuse if the ACTUAL pathname matches
147+ // This ensures /details/1 and /details/2 get separate view items and component instances
148+ const hasParams = routePath . includes ( ':' ) ;
149+ if ( hasParams ) {
150+ // Check if the existing view item's pathname matches the new pathname
151+ const existingPathname = v . routeData ?. match ?. pathname ;
152+ if ( existingPathname !== routeInfo . pathname ) {
153+ return false ; // Different param values, don't reuse
154+ }
155+ }
146156 return true ;
147157 }
148158 // Also reuse specific wildcard routes like tabs/*
@@ -153,9 +163,6 @@ export class ReactRouterViewStack extends ViewStacks {
153163 } ) ;
154164
155165 if ( existingViewItem ) {
156- console . log (
157- `[ReactRouterViewStack] Reusing existing view item ${ existingViewItem . id } for route ${ routeInfo . pathname } `
158- ) ;
159166 // Update and ensure the existing view item is properly configured
160167 existingViewItem . reactElement = reactElement ;
161168 existingViewItem . mount = true ;
@@ -177,10 +184,6 @@ export class ReactRouterViewStack extends ViewStacks {
177184 this . viewItemCounter ++ ;
178185 const id = `${ outletId } -${ this . viewItemCounter } ` ;
179186
180- console . log (
181- `[ReactRouterViewStack] Creating new view item ${ id } for route ${ routeInfo . pathname } with path: ${ routePath } `
182- ) ;
183-
184187 // Add infinite loop detection with a more reasonable limit
185188 // In complex navigation flows, we may have many view items across different outlets
186189 if ( this . viewItemCounter > 100 ) {
@@ -240,6 +243,15 @@ export class ReactRouterViewStack extends ViewStacks {
240243 }
241244 }
242245
246+ // For parameterized routes, check if this is a navigation to a different path instance
247+ // In that case, we should NOT reuse this view - a new view should be created
248+ const isParameterRoute = routePath . includes ( ':' ) ;
249+ const previousMatch = viewItem . routeData ?. match ;
250+ const isSamePath = match ?. pathname === previousMatch ?. pathname ;
251+
252+ // Flag to indicate this view should not be reused for this different parameterized path
253+ const shouldSkipForDifferentParam = isParameterRoute && match && previousMatch && ! isSamePath ;
254+
243255 // Cancel any pending deactivation if we have a match
244256 if ( match ) {
245257 const timeoutId = this . deactivationQueue . get ( viewItem . id ) ;
@@ -261,13 +273,9 @@ export class ReactRouterViewStack extends ViewStacks {
261273 ( typeof elementComponent . type === 'function' && elementComponent . type . name === 'Navigate' ) ) ;
262274
263275 if ( isNavigateComponent ) {
264- console . log (
265- `[ReactRouterViewStack] Navigate component detected for ${ viewItem . id } , match=${ ! ! match } , mount=${ viewItem . mount } `
266- ) ;
267276 // Navigate components should only be mounted when they match
268277 // Once they redirect (no longer match), they should be removed completely
269278 if ( ! match && viewItem . mount ) {
270- console . log ( `[ReactRouterViewStack] Unmounting Navigate component ${ viewItem . id } after redirect` ) ;
271279 viewItem . mount = false ;
272280 // Schedule removal of the Navigate view item after a short delay
273281 // This ensures the redirect completes before removal
@@ -306,7 +314,8 @@ export class ReactRouterViewStack extends ViewStacks {
306314 }
307315
308316 // Reactivate view if it matches but was previously deactivated
309- if ( match && ! viewItem . mount ) {
317+ // Don't reactivate if this is a parameterized route navigating to a different path instance
318+ if ( match && ! viewItem . mount && ! shouldSkipForDifferentParam ) {
310319 viewItem . mount = true ;
311320 viewItem . routeData . match = match ;
312321 }
@@ -334,10 +343,12 @@ export class ReactRouterViewStack extends ViewStacks {
334343
335344 const routeElement = React . cloneElement ( viewItem . reactElement ) ;
336345 const componentElement = routeElement . props . element ;
337- if ( match && viewItem . routeData . match !== match ) {
346+ // Don't update match for parameterized routes navigating to different path instances
347+ // This preserves the original match so that findViewItemByPath can correctly skip this view
348+ if ( match && viewItem . routeData . match !== match && ! shouldSkipForDifferentParam ) {
338349 viewItem . routeData . match = match ;
339350 }
340- const routeMatch = match || viewItem . routeData ?. match ;
351+ const routeMatch = shouldSkipForDifferentParam ? viewItem . routeData ?. match : ( match || viewItem . routeData ?. match ) ;
341352
342353 return (
343354 < RouteContext . Consumer key = { `view-context-${ viewItem . id } ` } >
@@ -756,6 +767,13 @@ export class ReactRouterViewStack extends ViewStacks {
756767 return false ;
757768 }
758769
770+ // For parameterized routes, never reuse if the pathname is different
771+ // This ensures /details/1 and /details/2 get separate view items
772+ const isParameterRoute = viewItemPath . includes ( ':' ) ;
773+ if ( isParameterRoute && ! isSamePath ) {
774+ return false ;
775+ }
776+
759777 // For routes without params, or when navigating to the exact same path,
760778 // or when there's no previous match, reuse the view item
761779 if ( ! hasParams || isSamePath || ! previousMatch ) {
@@ -764,12 +782,9 @@ export class ReactRouterViewStack extends ViewStacks {
764782 return true ;
765783 }
766784
767- // For parameterized/wildcard routes, only reuse if the pathname exactly matches
768- // This prevents reusing /details/1 when navigating to /details/2
785+ // For wildcard routes, only reuse if the pathname exactly matches
769786 const isWildcardRoute = viewItemPath . includes ( '*' ) ;
770- const isParameterRoute = viewItemPath . includes ( ':' ) ;
771-
772- if ( ( isParameterRoute || isWildcardRoute ) && isSamePath ) {
787+ if ( isWildcardRoute && isSamePath ) {
773788 match = result ;
774789 viewItem = v ;
775790 return true ;
0 commit comments