mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Fix double-adding fibers when traversing
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
export default function Toggle() {
|
||||
const [show, setShow] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<h2>Toggle</h2>
|
||||
<div>
|
||||
<>
|
||||
<button onClick={() => setShow(s => !s)}>Show child</button>
|
||||
{show && ' '}
|
||||
{show && <Greeting>Hello</Greeting>}
|
||||
</>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function Greeting({ children }) {
|
||||
return <p>{children}</p>;
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import ElementTypes from './ElementTypes';
|
||||
import InspectableElements from './InspectableElements';
|
||||
import InteractionTracing from './InteractionTracing';
|
||||
import ToDoList from './ToDoList';
|
||||
import Toggle from './Toggle';
|
||||
|
||||
import './styles.css';
|
||||
|
||||
@@ -31,6 +32,7 @@ function mountTestApp() {
|
||||
mountHelper(InspectableElements);
|
||||
mountHelper(ElementTypes);
|
||||
mountHelper(EditableProps);
|
||||
mountHelper(Toggle);
|
||||
mountHelper(DeeplyNestedComponents);
|
||||
}
|
||||
|
||||
|
||||
@@ -743,23 +743,26 @@ export function attach(
|
||||
}
|
||||
}
|
||||
|
||||
function mountFiber(fiber: Fiber, parentFiber: Fiber | null) {
|
||||
function mountFiber(
|
||||
fiber: Fiber,
|
||||
parentFiber: Fiber | null,
|
||||
traverseSiblings = false
|
||||
) {
|
||||
if (__DEBUG__) {
|
||||
debug('mountFiber()', fiber, parentFiber);
|
||||
}
|
||||
|
||||
const shouldEnqueueMount = !shouldFilterFiber(fiber);
|
||||
|
||||
if (shouldEnqueueMount) {
|
||||
enqueueMount(fiber, parentFiber);
|
||||
}
|
||||
|
||||
if (fiber.child !== null) {
|
||||
mountFiber(fiber.child, shouldEnqueueMount ? fiber : parentFiber);
|
||||
mountFiber(fiber.child, shouldEnqueueMount ? fiber : parentFiber, true);
|
||||
}
|
||||
|
||||
if (fiber.sibling) {
|
||||
mountFiber(fiber.sibling, parentFiber);
|
||||
if (traverseSiblings && fiber.sibling !== null) {
|
||||
mountFiber(fiber.sibling, parentFiber, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+36
-48
@@ -487,32 +487,26 @@ export default class Store extends EventEmitter {
|
||||
debug('Add', `new root fiber ${id}`);
|
||||
}
|
||||
|
||||
if (this._idToElement.has(id)) {
|
||||
// The renderer's tree walking approach sometimes mounts the same Fiber twice with Suspense and Lazy.
|
||||
// For now, we avoid adding it to the tree twice by checking if it's already been mounted.
|
||||
// Maybe in the future we'll revisit this.
|
||||
} else {
|
||||
const supportsProfiling = operations[i] > 0;
|
||||
i++;
|
||||
const supportsProfiling = operations[i] > 0;
|
||||
i++;
|
||||
|
||||
this._roots = this._roots.concat(id);
|
||||
this._rootIDToRendererID.set(id, rendererID);
|
||||
this._rootIDToCapabilities.set(id, { supportsProfiling });
|
||||
this._roots = this._roots.concat(id);
|
||||
this._rootIDToRendererID.set(id, rendererID);
|
||||
this._rootIDToCapabilities.set(id, { supportsProfiling });
|
||||
|
||||
this._idToElement.set(id, {
|
||||
children: [],
|
||||
depth: -1,
|
||||
displayName: null,
|
||||
id,
|
||||
key: null,
|
||||
ownerID: 0,
|
||||
parentID: 0,
|
||||
type,
|
||||
weight: 0,
|
||||
});
|
||||
this._idToElement.set(id, {
|
||||
children: [],
|
||||
depth: -1,
|
||||
displayName: null,
|
||||
id,
|
||||
key: null,
|
||||
ownerID: 0,
|
||||
parentID: 0,
|
||||
type,
|
||||
weight: 0,
|
||||
});
|
||||
|
||||
haveRootsChanged = true;
|
||||
}
|
||||
haveRootsChanged = true;
|
||||
} else {
|
||||
parentID = ((operations[i]: any): number);
|
||||
i++;
|
||||
@@ -545,35 +539,29 @@ export default class Store extends EventEmitter {
|
||||
);
|
||||
}
|
||||
|
||||
if (this._idToElement.has(id)) {
|
||||
// The renderer's tree walking approach sometimes mounts the same Fiber twice with Suspense and Lazy.
|
||||
// For now, we avoid adding it to the tree twice by checking if it's already been mounted.
|
||||
// Maybe in the future we'll revisit this.
|
||||
} else {
|
||||
parentElement = ((this._idToElement.get(parentID): any): Element);
|
||||
parentElement.children = parentElement.children.concat(id);
|
||||
parentElement = ((this._idToElement.get(parentID): any): Element);
|
||||
parentElement.children = parentElement.children.concat(id);
|
||||
|
||||
const element: Element = {
|
||||
children: [],
|
||||
depth: parentElement.depth + 1,
|
||||
displayName,
|
||||
id,
|
||||
key,
|
||||
ownerID,
|
||||
parentID: parentElement.id,
|
||||
type,
|
||||
weight: 1,
|
||||
};
|
||||
const element: Element = {
|
||||
children: [],
|
||||
depth: parentElement.depth + 1,
|
||||
displayName,
|
||||
id,
|
||||
key,
|
||||
ownerID,
|
||||
parentID: parentElement.id,
|
||||
type,
|
||||
weight: 1,
|
||||
};
|
||||
|
||||
this._idToElement.set(id, element);
|
||||
this._idToElement.set(id, element);
|
||||
|
||||
const oldAddedElementIDs = addedElementIDs;
|
||||
addedElementIDs = new Uint32Array(addedElementIDs.length + 1);
|
||||
addedElementIDs.set(oldAddedElementIDs);
|
||||
addedElementIDs[oldAddedElementIDs.length] = id;
|
||||
const oldAddedElementIDs = addedElementIDs;
|
||||
addedElementIDs = new Uint32Array(addedElementIDs.length + 1);
|
||||
addedElementIDs.set(oldAddedElementIDs);
|
||||
addedElementIDs[oldAddedElementIDs.length] = id;
|
||||
|
||||
weightDelta = 1;
|
||||
}
|
||||
weightDelta = 1;
|
||||
}
|
||||
break;
|
||||
case TREE_OPERATION_REMOVE:
|
||||
|
||||
Reference in New Issue
Block a user