[DevTools] Preserve the original index when sorting suspended by (#34829)
The index is both used as the key and for hydration purposes. Previously we didn't preserve the index when sorting so the index didn't line up which caused hydration to be the wrong slot when sorted.
Sebastian Markbåge committed
Oct 13, 2025 at 12:12 UTC
d7215b4970858ea45db924e1ec435a9a3e5cff40
1 file changed
+29
-6
packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSuspendedBy.js
+29
-6
@@ -300,9 +300,31 @@ type Props = {
300
store: Store,
301
};
302
303
-function compareTime(a: SerializedAsyncInfo, b: SerializedAsyncInfo): number {
304
- const ioA = a.awaited;
305
- const ioB = b.awaited;
303
+function withIndex(
304
+ value: SerializedAsyncInfo,
305
+ index: number,
306
+): {
307
+ index: number,
308
+ value: SerializedAsyncInfo,
309
+} {
310
+ return {
311
+ index,
312
+ value,
313
+ };
314
+}
315
+
316
+function compareTime(
317
+ a: {
318
+ index: number,
319
+ value: SerializedAsyncInfo,
320
+ },
321
+ b: {
322
+ index: number,
323
+ value: SerializedAsyncInfo,
324
+ },
325
+): number {
326
+ const ioA = a.value.awaited;
327
+ const ioB = b.value.awaited;
328
if (ioA.start === ioB.start) {
329
return ioA.end - ioB.end;
330
}
@@ -364,7 +386,8 @@ export default function InspectedElementSuspendedBy({
386
minTime = maxTime - 25;
387
}
388
367
- const sortedSuspendedBy = suspendedBy === null ? [] : suspendedBy.slice(0);
389
+ const sortedSuspendedBy =
390
+ suspendedBy === null ? [] : suspendedBy.map(withIndex);
391
sortedSuspendedBy.sort(compareTime);
392
393
let unknownSuspenders = null;
@@ -407,11 +430,11 @@ export default function InspectedElementSuspendedBy({
430
<ButtonIcon type="copy" />
431
</Button>
432
</div>
410
- {sortedSuspendedBy.map((asyncInfo, index) => (
433
+ {sortedSuspendedBy.map(({value, index}) => (
434
<SuspendedByRow
435
key={index}
436
index={index}
414
- asyncInfo={asyncInfo}
437
+ asyncInfo={value}
438
bridge={bridge}
439
element={element}
440
inspectedElement={inspectedElement}