[Persistent] Finalize children after we've actually inserted them (#12300)

The order of this was wrong. We also unconditionally mark for updates so
killed that unused branch.
This commit is contained in:
Sebastian Markbåge 2018-02-26 23:34:53 -08:00 committed by GitHub
parent 8e5f12ca6c
commit db47031e63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 14 deletions

View File

@ -14,18 +14,26 @@ const invariant = require('fbjs/lib/invariant');
const roots = new Map();
const allocatedTags = new Set();
function dumpSubtree(info, indent) {
let out = '';
out += ' '.repeat(indent) + info.viewName + ' ' + JSON.stringify(info.props);
// eslint-disable-next-line no-for-of-loops/no-for-of-loops
for (const child of info.children) {
out += '\n' + dumpSubtree(child, indent + 2);
}
return out;
}
const RCTFabricUIManager = {
__dumpHierarchyForJestTestsOnly: function() {
function dumpSubtree(info, indent) {
let out = '';
out +=
' '.repeat(indent) + info.viewName + ' ' + JSON.stringify(info.props);
// eslint-disable-next-line no-for-of-loops/no-for-of-loops
for (const child of info.children) {
out += '\n' + dumpSubtree(child, indent + 2);
}
return out;
__dumpChildSetForJestTestsOnly: function(childSet) {
let result = [];
// eslint-disable-next-line no-for-of-loops/no-for-of-loops
for (const child of childSet) {
result.push(dumpSubtree(child, 0));
}
return result.join('\n');
},
__dumpHierarchyForJestTestsOnly: function() {
let result = [];
// eslint-disable-next-line no-for-of-loops/no-for-of-loops
for (const [rootTag, childSet] of roots) {

View File

@ -247,4 +247,29 @@ describe('ReactFabric', () => {
ReactFabric.render(<Component />, 11);
expect(mockArgs.length).toEqual(0);
});
it('should call complete after inserting children', () => {
const View = createReactNativeComponentClass('View', () => ({
validAttributes: {foo: true},
uiViewClassName: 'View',
}));
const snapshots = [];
FabricUIManager.completeRoot.mockImplementation(function(
rootTag,
newChildSet,
) {
snapshots.push(
FabricUIManager.__dumpChildSetForJestTestsOnly(newChildSet),
);
});
ReactFabric.render(
<View foo="a">
<View foo="b" />
</View>,
22,
);
expect(snapshots).toMatchSnapshot();
});
});

View File

@ -50,6 +50,13 @@ exports[`ReactFabric renders and reorders children 2`] = `
View {\\"title\\":\\"y\\"}"
`;
exports[`ReactFabric should call complete after inserting children 1`] = `
Array [
"View {\\"foo\\":\\"a\\"}
View {\\"foo\\":\\"b\\"}",
]
`;
exports[`ReactFabric should only pass props diffs to FabricUIManager.cloneNode 1`] = `
"11
View {\\"foo\\":\\"a\\",\\"bar\\":\\"b\\"}

View File

@ -281,14 +281,12 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
} else {
const container = portalOrRoot.containerInfo;
let newChildSet = createContainerChildSet(container);
if (finalizeContainerChildren(container, newChildSet)) {
markUpdate(workInProgress);
}
portalOrRoot.pendingChildren = newChildSet;
// If children might have changed, we have to add them all to the set.
appendAllChildrenToContainer(newChildSet, workInProgress);
portalOrRoot.pendingChildren = newChildSet;
// Schedule an update on the container to swap out the container.
markUpdate(workInProgress);
finalizeContainerChildren(container, newChildSet);
}
};
updateHostComponent = function(