@samitouri / QOS-React / commits / f634b813e1

Handle Bailed Out HostText update and MultiChildText test (#8371)

This handles the case where a host text bails out. In that case we need to reuse its previous memoizedProps. We should also only schedule an actual update if it did actually change its text content. I updated the unit test to ignore comment nodes if we're using Fiber.

Sebastian Markbåge committed Nov 28, 2016 at 17:26 UTC f634b813e121d1d81d8fbd5007990e8e59824491
2 files changed +41 -22
src/renderers/shared/fiber/ReactFiberCompleteWork.js
+14 -3
@@ -249,9 +249,20 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
249 case HostText:
250 let newText = workInProgress.pendingProps;
251 if (current && workInProgress.stateNode != null) {
252 - // If we have an alternate, that means this is an update and we need to
253 - // schedule a side-effect to do the updates.
254 - markUpdate(workInProgress);
252 + const oldText = current.memoizedProps;
253 + if (newText === null) {
254 + // If this was a bail out we need to fall back to memoized text.
255 + // This works the same way as HostComponent.
256 + newText = workInProgress.memoizedProps;
257 + if (newText === null) {
258 + newText = oldText;
259 + }
260 + }
261 + // If we have an alternate, that means this is an update and we need
262 + // to schedule a side-effect to do the updates.
263 + if (oldText !== newText) {
264 + markUpdate(workInProgress);
265 + }
266 } else {
267 if (typeof newText !== 'string') {
268 if (workInProgress.stateNode === null) {
src/renderers/shared/shared/__tests__/ReactMultiChildText-test.js
+27 -19
@@ -13,6 +13,7 @@
13
14 var React = require('React');
15 var ReactDOM = require('ReactDOM');
16 +var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
17 var ReactTestUtils = require('ReactTestUtils');
18
19 // Helpers
@@ -57,28 +58,35 @@ var expectChildren = function(container, children) {
58 var child = children[i];
59
60 if (typeof child === 'string') {
60 - openingCommentNode = outerNode.childNodes[mountIndex];
61 -
62 - expect(openingCommentNode.nodeType).toBe(8);
63 - expect(openingCommentNode.nodeValue).toMatch(/ react-text: [0-9]+ /);
64 -
65 - if (child === '') {
66 - textNode = null;
67 - closingCommentNode = openingCommentNode.nextSibling;
68 - mountIndex += 2;
69 - } else {
70 - textNode = openingCommentNode.nextSibling;
71 - closingCommentNode = textNode.nextSibling;
72 - mountIndex += 3;
73 - }
74 -
75 - if (textNode) {
61 + if (ReactDOMFeatureFlags.useFiber) {
62 + textNode = outerNode.childNodes[mountIndex];
63 expect(textNode.nodeType).toBe(3);
64 expect(textNode.data).toBe('' + child);
65 + mountIndex++;
66 + } else {
67 + openingCommentNode = outerNode.childNodes[mountIndex];
68 +
69 + expect(openingCommentNode.nodeType).toBe(8);
70 + expect(openingCommentNode.nodeValue).toMatch(/ react-text: [0-9]+ /);
71 +
72 + if (child === '') {
73 + textNode = null;
74 + closingCommentNode = openingCommentNode.nextSibling;
75 + mountIndex += 2;
76 + } else {
77 + textNode = openingCommentNode.nextSibling;
78 + closingCommentNode = textNode.nextSibling;
79 + mountIndex += 3;
80 + }
81 +
82 + if (textNode) {
83 + expect(textNode.nodeType).toBe(3);
84 + expect(textNode.data).toBe('' + child);
85 + }
86 +
87 + expect(closingCommentNode.nodeType).toBe(8);
88 + expect(closingCommentNode.nodeValue).toBe(' /react-text ');
89 }
79 -
80 - expect(closingCommentNode.nodeType).toBe(8);
81 - expect(closingCommentNode.nodeValue).toBe(' /react-text ');
90 } else {
91 var elementDOMNode = outerNode.childNodes[mountIndex];
92 expect(elementDOMNode.tagName).toBe('DIV');