Skip to content

Commit cf6e502

Browse files
authored
Hot reloading: Avoid stack overflow on wide trees (facebook#34145)
Every sibling added to the stack here. Not sure this needs to be recursive at all but certainly for siblings this can just be a loop.
1 parent 3958d5d commit cf6e502

File tree

1 file changed

+59
-59
lines changed

1 file changed

+59
-59
lines changed

packages/react-reconciler/src/ReactFiberHotReloading.js

Lines changed: 59 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -261,74 +261,74 @@ function scheduleFibersWithFamiliesRecursively(
261261
staleFamilies: Set<Family>,
262262
): void {
263263
if (__DEV__) {
264-
const {alternate, child, sibling, tag, type} = fiber;
264+
do {
265+
const {alternate, child, sibling, tag, type} = fiber;
265266

266-
let candidateType = null;
267-
switch (tag) {
268-
case FunctionComponent:
269-
case SimpleMemoComponent:
270-
case ClassComponent:
271-
candidateType = type;
272-
break;
273-
case ForwardRef:
274-
candidateType = type.render;
275-
break;
276-
default:
277-
break;
278-
}
267+
let candidateType = null;
268+
switch (tag) {
269+
case FunctionComponent:
270+
case SimpleMemoComponent:
271+
case ClassComponent:
272+
candidateType = type;
273+
break;
274+
case ForwardRef:
275+
candidateType = type.render;
276+
break;
277+
default:
278+
break;
279+
}
279280

280-
if (resolveFamily === null) {
281-
throw new Error('Expected resolveFamily to be set during hot reload.');
282-
}
281+
if (resolveFamily === null) {
282+
throw new Error('Expected resolveFamily to be set during hot reload.');
283+
}
283284

284-
let needsRender = false;
285-
let needsRemount = false;
286-
if (candidateType !== null) {
287-
const family = resolveFamily(candidateType);
288-
if (family !== undefined) {
289-
if (staleFamilies.has(family)) {
290-
needsRemount = true;
291-
} else if (updatedFamilies.has(family)) {
292-
if (tag === ClassComponent) {
285+
let needsRender = false;
286+
let needsRemount = false;
287+
if (candidateType !== null) {
288+
const family = resolveFamily(candidateType);
289+
if (family !== undefined) {
290+
if (staleFamilies.has(family)) {
293291
needsRemount = true;
294-
} else {
295-
needsRender = true;
292+
} else if (updatedFamilies.has(family)) {
293+
if (tag === ClassComponent) {
294+
needsRemount = true;
295+
} else {
296+
needsRender = true;
297+
}
296298
}
297299
}
298300
}
299-
}
300-
if (failedBoundaries !== null) {
301-
if (
302-
failedBoundaries.has(fiber) ||
303-
// $FlowFixMe[incompatible-use] found when upgrading Flow
304-
(alternate !== null && failedBoundaries.has(alternate))
305-
) {
306-
needsRemount = true;
301+
if (failedBoundaries !== null) {
302+
if (
303+
failedBoundaries.has(fiber) ||
304+
// $FlowFixMe[incompatible-use] found when upgrading Flow
305+
(alternate !== null && failedBoundaries.has(alternate))
306+
) {
307+
needsRemount = true;
308+
}
307309
}
308-
}
309310

310-
if (needsRemount) {
311-
fiber._debugNeedsRemount = true;
312-
}
313-
if (needsRemount || needsRender) {
314-
const root = enqueueConcurrentRenderForLane(fiber, SyncLane);
315-
if (root !== null) {
316-
scheduleUpdateOnFiber(root, fiber, SyncLane);
311+
if (needsRemount) {
312+
fiber._debugNeedsRemount = true;
317313
}
318-
}
319-
if (child !== null && !needsRemount) {
320-
scheduleFibersWithFamiliesRecursively(
321-
child,
322-
updatedFamilies,
323-
staleFamilies,
324-
);
325-
}
326-
if (sibling !== null) {
327-
scheduleFibersWithFamiliesRecursively(
328-
sibling,
329-
updatedFamilies,
330-
staleFamilies,
331-
);
332-
}
314+
if (needsRemount || needsRender) {
315+
const root = enqueueConcurrentRenderForLane(fiber, SyncLane);
316+
if (root !== null) {
317+
scheduleUpdateOnFiber(root, fiber, SyncLane);
318+
}
319+
}
320+
if (child !== null && !needsRemount) {
321+
scheduleFibersWithFamiliesRecursively(
322+
child,
323+
updatedFamilies,
324+
staleFamilies,
325+
);
326+
}
327+
328+
if (sibling === null) {
329+
break;
330+
}
331+
fiber = sibling;
332+
} while (true);
333333
}
334334
}

0 commit comments

Comments
 (0)