@@ -131,17 +131,8 @@ function handleNavigation(
131
131
location : Location ,
132
132
routes : RouteObject [ ] ,
133
133
navigationType : Action ,
134
- isBaseLocation : boolean ,
135
134
matches ?: AgnosticDataRouteMatch ,
136
135
) : void {
137
- if ( isBaseLocation ) {
138
- if ( activeTransaction ) {
139
- activeTransaction . finish ( ) ;
140
- }
141
-
142
- return ;
143
- }
144
-
145
136
const branches = Array . isArray ( matches ) ? matches : _matchRoutes ( routes , location ) ;
146
137
147
138
if ( _startTransactionOnLocationChange && ( navigationType === 'PUSH' || navigationType === 'POP' ) && branches ) {
@@ -179,28 +170,27 @@ export function withSentryReactRouterV6Routing<P extends Record<string, any>, R
179
170
return Routes ;
180
171
}
181
172
182
- let isBaseLocation : boolean = false ;
183
- let routes : RouteObject [ ] ;
173
+ let isMountRenderPass : boolean = true ;
184
174
185
175
const SentryRoutes : React . FC < P > = ( props : P ) => {
186
176
const location = _useLocation ( ) ;
187
177
const navigationType = _useNavigationType ( ) ;
188
178
189
- _useEffect ( ( ) => {
190
- // Performance concern:
191
- // This is repeated when <Routes /> is rendered.
192
- routes = _createRoutesFromChildren ( props . children ) as RouteObject [ ] ;
193
- isBaseLocation = true ;
194
-
195
- updatePageloadTransaction ( location , routes ) ;
196
- // eslint-disable-next-line react-hooks/exhaustive-deps
197
- } , [ props . children ] ) ;
179
+ _useEffect (
180
+ ( ) => {
181
+ const routes = _createRoutesFromChildren ( props . children ) as RouteObject [ ] ;
198
182
199
- _useEffect ( ( ) => {
200
- handleNavigation ( location , routes , navigationType , isBaseLocation ) ;
201
- } , [ props . children , location , navigationType , isBaseLocation ] ) ;
202
-
203
- isBaseLocation = false ;
183
+ if ( isMountRenderPass ) {
184
+ updatePageloadTransaction ( location , routes ) ;
185
+ isMountRenderPass = false ;
186
+ } else {
187
+ handleNavigation ( location , routes , navigationType ) ;
188
+ }
189
+ } ,
190
+ // `props.children` is purpusely not included in the dependency array, because we do not want to re-run this effect
191
+ // when the children change. We only want to start transactions when the location or navigation type change.
192
+ [ location , navigationType ] ,
193
+ ) ;
204
194
205
195
// @ts -ignore Setting more specific React Component typing for `R` generic above
206
196
// will break advanced type inference done by react router params
@@ -224,28 +214,33 @@ export function wrapUseRoutes(origUseRoutes: UseRoutes): UseRoutes {
224
214
return origUseRoutes ;
225
215
}
226
216
227
- let isBaseLocation : boolean = false ;
217
+ let isMountRenderPass : boolean = true ;
228
218
229
219
// eslint-disable-next-line react/display-name
230
- return ( routes : RouteObject [ ] , location ?: Partial < Location > | string ) : React . ReactElement | null => {
231
- const SentryRoutes : React . FC < unknown > = ( props : unknown ) => {
232
- const Routes = origUseRoutes ( routes , location ) ;
220
+ return ( routes : RouteObject [ ] , locationArg ?: Partial < Location > | string ) : React . ReactElement | null => {
221
+ const SentryRoutes : React . FC < unknown > = ( ) => {
222
+ const Routes = origUseRoutes ( routes , locationArg ) ;
233
223
234
- const locationArgObject = typeof location === 'string' ? { pathname : location } : location ;
235
- const locationObject = ( locationArgObject as Location ) || _useLocation ( ) ;
224
+ const location = _useLocation ( ) ;
236
225
const navigationType = _useNavigationType ( ) ;
237
226
238
- _useEffect ( ( ) => {
239
- isBaseLocation = true ;
240
-
241
- updatePageloadTransaction ( locationObject , routes ) ;
242
- } , [ props ] ) ;
227
+ // A value with stable identity to either pick `locationArg` if available or `location` if not
228
+ const stableLocationParam =
229
+ typeof locationArg === 'string' || locationArg ?. pathname !== undefined
230
+ ? ( locationArg as { pathname : string } )
231
+ : location ;
243
232
244
233
_useEffect ( ( ) => {
245
- handleNavigation ( locationObject , routes , navigationType , isBaseLocation ) ;
246
- } , [ props , locationObject , navigationType , isBaseLocation ] ) ;
247
-
248
- isBaseLocation = false ;
234
+ const normalizedLocation =
235
+ typeof stableLocationParam === 'string' ? { pathname : stableLocationParam } : stableLocationParam ;
236
+
237
+ if ( isMountRenderPass ) {
238
+ updatePageloadTransaction ( normalizedLocation , routes ) ;
239
+ isMountRenderPass = false ;
240
+ } else {
241
+ handleNavigation ( normalizedLocation , routes , navigationType ) ;
242
+ }
243
+ } , [ navigationType , stableLocationParam ] ) ;
249
244
250
245
return Routes ;
251
246
} ;
@@ -275,7 +270,7 @@ export function wrapCreateBrowserRouter(createRouterFunction: CreateRouterFuncti
275
270
( state . historyAction === 'PUSH' || state . historyAction === 'POP' ) &&
276
271
activeTransaction
277
272
) {
278
- handleNavigation ( location , routes , state . historyAction , false ) ;
273
+ handleNavigation ( location , routes , state . historyAction ) ;
279
274
}
280
275
} ) ;
281
276
0 commit comments