@samitouri / QOS-React-2 / commits / 13f01be64f

Enable text updates in ReactNoop

We'll enable updating of text nodes. To be able to test that we need the text nodes to be mutable. They're currently just strings in the Noop renderer so this makes them an object instead. That exposed a bug in ReactFiberCommitWork for text nodes.

Sebastian Markbage committed Sep 19, 2016 at 15:26 UTC 13f01be64f92b3c9a693b40506c4c2972ccfe4eb
3 files changed +14 -11
src/renderers/noop/ReactNoop.js
+10 -6
@@ -32,11 +32,12 @@ var scheduledAnimationCallback = null;
32 var scheduledDeferredCallback = null;
33
34 const TERMINAL_TAG = 99;
35 +const TEXT_TAG = 98;
36
37 type Container = { rootID: number, children: Array<Instance | TextInstance> };
38 type Props = { prop: any };
39 type Instance = { tag: 99, type: string, id: number, children: Array<Instance | TextInstance>, prop: any };
39 -type TextInstance = string;
40 +type TextInstance = { tag: 98, text: string };
41
42 var instanceCounter = 0;
43
@@ -44,7 +45,7 @@ function recursivelyAppendChildren(flatArray : Array<Instance | TextInstance>, c
45 if (!child) {
46 return;
47 }
47 - if (typeof child === 'string' || child.tag === TERMINAL_TAG) {
48 + if (child.tag === TERMINAL_TAG || child.tag === TEXT_TAG) {
49 flatArray.push(child);
50 } else {
51 let node = child;
@@ -93,11 +94,14 @@ var NoopRenderer = ReactFiberReconciler({
94 },
95
96 createTextInstance(text : string) : TextInstance {
96 - return text;
97 + var inst = { tag: TEXT_TAG, text : text };
98 + // Hide from unit tests
99 + Object.defineProperty(inst, 'tag', { value: inst.tag, enumerable: false });
100 + return inst;
101 },
102
103 commitTextUpdate(textInstance : TextInstance, oldText : string, newText : string) : void {
100 - // Not yet supported.
104 + textInstance.text = newText;
105 },
106
107 scheduleAnimationCallback(callback) {
@@ -178,8 +182,8 @@ var ReactNoop = {
182 function logHostInstances(children: Array<Instance | TextInstance>, depth) {
183 for (var i = 0; i < children.length; i++) {
184 var child = children[i];
181 - if (typeof child === 'string') {
182 - log(' '.repeat(depth) + '- ' + child);
185 + if (child.tag === TEXT_TAG) {
186 + log(' '.repeat(depth) + '- ' + child.text);
187 } else {
188 log(' '.repeat(depth) + '- ' + child.type + '#' + child.id);
189 logHostInstances(child.children, depth + 1);
src/renderers/shared/fiber/ReactFiberCommitWork.js
+3 -5
@@ -74,13 +74,11 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
74 if (finishedWork.stateNode == null || !current) {
75 throw new Error('This should only be done during updates.');
76 }
77 - // TODO: This never gets called yet because I don't have update support
78 - // for text nodes. This only gets updated through a host component or
79 - // container updating with this as one of its child nodes.
77 const textInstance : TI = finishedWork.stateNode;
81 - const oldText : string = finishedWork.memoizedProps;
82 - const newText : string = current.memoizedProps;
78 + const newText : string = finishedWork.memoizedProps;
79 + const oldText : string = current.memoizedProps;
80 commitTextUpdate(textInstance, oldText, newText);
81 + return;
82 }
83 default:
84 throw new Error('This unit of work tag should not have side-effects.');
src/renderers/shared/fiber/__tests__/ReactIncrementalSideEffects-test.js
+1
@@ -21,6 +21,7 @@ describe('ReactIncrementalSideEffects', () => {
21 });
22
23 function div(...children) {
24 + children = children.map(c => typeof c === 'string' ? { text: c } : c);
25 return { type: 'div', children, prop: undefined };
26 }
27