Use HostContext to warn about invalid View/Text nesting (#12766)
Brian Vaughn committed
May 14, 2018 at 15:34 UTC
c802d29bd16753aef15863db8fb3f338c0067c75
8 files changed
+352
-141
packages/react-native-renderer/src/ReactFabricRenderer.js
+37
-8
@@ -22,7 +22,7 @@ import * as ReactNativeViewConfigRegistry from 'ReactNativeViewConfigRegistry';
22
import ReactFiberReconciler from 'react-reconciler';
23
24
import deepFreezeAndThrowOnMutationInDev from 'deepFreezeAndThrowOnMutationInDev';
25
-import emptyObject from 'fbjs/lib/emptyObject';
25
+import invariant from 'fbjs/lib/invariant';
26
27
// Modules provided by RN:
28
import TextInputState from 'TextInputState';
@@ -35,6 +35,10 @@ import UIManager from 'UIManager';
35
// This means that they never overlap.
36
let nextReactTag = 2;
37
38
+type HostContext = $ReadOnly<{|
39
+ isInAParentText: boolean,
40
+|}>;
41
+
42
/**
43
* This is used for refs on host components.
44
*/
@@ -135,7 +139,7 @@ const ReactFabricRenderer = ReactFiberReconciler({
139
type: string,
140
props: Props,
141
rootContainerInstance: Container,
138
- hostContext: {},
142
+ hostContext: HostContext,
143
internalInstanceHandle: Object,
144
): Instance {
145
const tag = nextReactTag;
@@ -151,6 +155,11 @@ const ReactFabricRenderer = ReactFiberReconciler({
155
}
156
}
157
158
+ invariant(
159
+ type !== 'RCTView' || !hostContext.isInAParentText,
160
+ 'Nesting of <View> within <Text> is not currently supported.',
161
+ );
162
+
163
const updatePayload = ReactNativeAttributePayload.create(
164
props,
165
viewConfig.validAttributes,
@@ -175,9 +184,14 @@ const ReactFabricRenderer = ReactFiberReconciler({
184
createTextInstance(
185
text: string,
186
rootContainerInstance: Container,
178
- hostContext: {},
187
+ hostContext: HostContext,
188
internalInstanceHandle: Object,
189
): TextInstance {
190
+ invariant(
191
+ hostContext.isInAParentText,
192
+ 'Text strings must be rendered within a <Text> component.',
193
+ );
194
+
195
const tag = nextReactTag;
196
nextReactTag += 2;
197
@@ -203,12 +217,27 @@ const ReactFabricRenderer = ReactFiberReconciler({
217
return false;
218
},
219
206
- getRootHostContext(): {} {
207
- return emptyObject;
220
+ getRootHostContext(rootContainerInstance: Container): HostContext {
221
+ return {isInAParentText: false};
222
},
223
210
- getChildHostContext(): {} {
211
- return emptyObject;
224
+ getChildHostContext(
225
+ parentHostContext: HostContext,
226
+ type: string,
227
+ ): HostContext {
228
+ const prevIsInAParentText = parentHostContext.isInAParentText;
229
+ const isInAParentText =
230
+ type === 'AndroidTextInput' || // Android
231
+ type === 'RCTMultilineTextInputView' || // iOS
232
+ type === 'RCTSinglelineTextInputView' || // iOS
233
+ type === 'RCTText' ||
234
+ type === 'RCTVirtualText';
235
+
236
+ if (prevIsInAParentText !== isInAParentText) {
237
+ return {isInAParentText};
238
+ } else {
239
+ return parentHostContext;
240
+ }
241
},
242
243
getPublicInstance(instance) {
@@ -230,7 +259,7 @@ const ReactFabricRenderer = ReactFiberReconciler({
259
oldProps: Props,
260
newProps: Props,
261
rootContainerInstance: Container,
233
- hostContext: {},
262
+ hostContext: HostContext,
263
): null | Object {
264
const viewConfig = instance.canonical.viewConfig;
265
const updatePayload = ReactNativeAttributePayload.diff(
packages/react-native-renderer/src/ReactNativeFiberRenderer.js
+37
-7
@@ -12,6 +12,7 @@ import type {ReactNativeBaseComponentViewConfig} from './ReactNativeTypes';
12
import ReactFiberReconciler from 'react-reconciler';
13
import emptyObject from 'fbjs/lib/emptyObject';
14
import invariant from 'fbjs/lib/invariant';
15
+
16
// Modules provided by RN:
17
import UIManager from 'UIManager';
18
import deepFreezeAndThrowOnMutationInDev from 'deepFreezeAndThrowOnMutationInDev';
@@ -35,6 +36,10 @@ export type Instance = {
36
type Props = Object;
37
type TextInstance = number;
38
39
+type HostContext = $ReadOnly<{|
40
+ isInAParentText: boolean,
41
+|}>;
42
+
43
// Counter for uniquely identifying views.
44
// % 10 === 1 means it is a rootTag.
45
// % 2 === 0 means it is a Fabric tag.
@@ -71,7 +76,7 @@ const NativeRenderer = ReactFiberReconciler({
76
type: string,
77
props: Props,
78
rootContainerInstance: Container,
74
- hostContext: {},
79
+ hostContext: HostContext,
80
internalInstanceHandle: Object,
81
): Instance {
82
const tag = allocateTag();
@@ -85,6 +90,11 @@ const NativeRenderer = ReactFiberReconciler({
90
}
91
}
92
93
+ invariant(
94
+ type !== 'RCTView' || !hostContext.isInAParentText,
95
+ 'Nesting of <View> within <Text> is not currently supported.',
96
+ );
97
+
98
const updatePayload = ReactNativeAttributePayload.create(
99
props,
100
viewConfig.validAttributes,
@@ -110,9 +120,14 @@ const NativeRenderer = ReactFiberReconciler({
120
createTextInstance(
121
text: string,
122
rootContainerInstance: Container,
113
- hostContext: {},
123
+ hostContext: HostContext,
124
internalInstanceHandle: Object,
125
): TextInstance {
126
+ invariant(
127
+ hostContext.isInAParentText,
128
+ 'Text strings must be rendered within a <Text> component.',
129
+ );
130
+
131
const tag = allocateTag();
132
133
UIManager.createView(
@@ -155,12 +170,27 @@ const NativeRenderer = ReactFiberReconciler({
170
return false;
171
},
172
158
- getRootHostContext(): {} {
159
- return emptyObject;
173
+ getRootHostContext(rootContainerInstance: Container): HostContext {
174
+ return {isInAParentText: false};
175
},
176
162
- getChildHostContext(): {} {
163
- return emptyObject;
177
+ getChildHostContext(
178
+ parentHostContext: HostContext,
179
+ type: string,
180
+ ): HostContext {
181
+ const prevIsInAParentText = parentHostContext.isInAParentText;
182
+ const isInAParentText =
183
+ type === 'AndroidTextInput' || // Android
184
+ type === 'RCTMultilineTextInputView' || // iOS
185
+ type === 'RCTSinglelineTextInputView' || // iOS
186
+ type === 'RCTText' ||
187
+ type === 'RCTVirtualText';
188
+
189
+ if (prevIsInAParentText !== isInAParentText) {
190
+ return {isInAParentText};
191
+ } else {
192
+ return parentHostContext;
193
+ }
194
},
195
196
getPublicInstance(instance) {
@@ -181,7 +211,7 @@ const NativeRenderer = ReactFiberReconciler({
211
oldProps: Props,
212
newProps: Props,
213
rootContainerInstance: Container,
184
- hostContext: {},
214
+ hostContext: HostContext,
215
): null | Object {
216
return emptyObject;
217
},
packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js
+98
-22
@@ -33,9 +33,9 @@ describe('ReactFabric', () => {
33
});
34
35
it('should be able to create and render a native component', () => {
36
- const View = createReactNativeComponentClass('View', () => ({
36
+ const View = createReactNativeComponentClass('RCTView', () => ({
37
validAttributes: {foo: true},
38
- uiViewClassName: 'View',
38
+ uiViewClassName: 'RCTView',
39
}));
40
41
ReactFabric.render(<View foo="test" />, 1);
@@ -45,9 +45,9 @@ describe('ReactFabric', () => {
45
});
46
47
it('should be able to create and update a native component', () => {
48
- const View = createReactNativeComponentClass('View', () => ({
48
+ const View = createReactNativeComponentClass('RCTView', () => ({
49
validAttributes: {foo: true},
50
- uiViewClassName: 'View',
50
+ uiViewClassName: 'RCTView',
51
}));
52
53
const firstNode = {};
@@ -67,9 +67,9 @@ describe('ReactFabric', () => {
67
});
68
69
it('should not call FabricUIManager.cloneNode after render for properties that have not changed', () => {
70
- const Text = createReactNativeComponentClass('Text', () => ({
70
+ const Text = createReactNativeComponentClass('RCTText', () => ({
71
validAttributes: {foo: true},
72
- uiViewClassName: 'Text',
72
+ uiViewClassName: 'RCTText',
73
}));
74
75
ReactFabric.render(<Text foo="a">1</Text>, 11);
@@ -110,15 +110,15 @@ describe('ReactFabric', () => {
110
});
111
112
it('should only pass props diffs to FabricUIManager.cloneNode', () => {
113
- const View = createReactNativeComponentClass('View', () => ({
113
+ const Text = createReactNativeComponentClass('RCTText', () => ({
114
validAttributes: {foo: true, bar: true},
115
- uiViewClassName: 'View',
115
+ uiViewClassName: 'RCTText',
116
}));
117
118
ReactFabric.render(
119
- <View foo="a" bar="a">
119
+ <Text foo="a" bar="a">
120
1
121
- </View>,
121
+ </Text>,
122
11,
123
);
124
expect(FabricUIManager.cloneNode).not.toBeCalled();
@@ -127,9 +127,9 @@ describe('ReactFabric', () => {
127
expect(FabricUIManager.cloneNodeWithNewChildrenAndProps).not.toBeCalled();
128
129
ReactFabric.render(
130
- <View foo="a" bar="b">
130
+ <Text foo="a" bar="b">
131
1
132
- </View>,
132
+ </Text>,
133
11,
134
);
135
expect(FabricUIManager.cloneNodeWithNewProps.mock.calls[0][1]).toEqual({
@@ -138,9 +138,9 @@ describe('ReactFabric', () => {
138
expect(FabricUIManager.__dumpHierarchyForJestTestsOnly()).toMatchSnapshot();
139
140
ReactFabric.render(
141
- <View foo="b" bar="b">
141
+ <Text foo="b" bar="b">
142
2
143
- </View>,
143
+ </Text>,
144
11,
145
);
146
expect(
@@ -152,9 +152,9 @@ describe('ReactFabric', () => {
152
});
153
154
it('should not call UIManager.updateView from setNativeProps for properties that have not changed', () => {
155
- const View = createReactNativeComponentClass('View', () => ({
155
+ const View = createReactNativeComponentClass('RCTView', () => ({
156
validAttributes: {foo: true},
157
- uiViewClassName: 'View',
157
+ uiViewClassName: 'RCTView',
158
}));
159
160
class Subclass extends ReactFabric.NativeComponent {
@@ -187,9 +187,9 @@ describe('ReactFabric', () => {
187
});
188
189
it('returns the correct instance and calls it in the callback', () => {
190
- const View = createReactNativeComponentClass('View', () => ({
190
+ const View = createReactNativeComponentClass('RCTView', () => ({
191
validAttributes: {foo: true},
192
- uiViewClassName: 'View',
192
+ uiViewClassName: 'RCTView',
193
}));
194
195
let a;
@@ -208,9 +208,9 @@ describe('ReactFabric', () => {
208
});
209
210
it('renders and reorders children', () => {
211
- const View = createReactNativeComponentClass('View', () => ({
211
+ const View = createReactNativeComponentClass('RCTView', () => ({
212
validAttributes: {title: true},
213
- uiViewClassName: 'View',
213
+ uiViewClassName: 'RCTView',
214
}));
215
216
class Component extends React.Component {
@@ -249,9 +249,9 @@ describe('ReactFabric', () => {
249
});
250
251
it('should call complete after inserting children', () => {
252
- const View = createReactNativeComponentClass('View', () => ({
252
+ const View = createReactNativeComponentClass('RCTView', () => ({
253
validAttributes: {foo: true},
254
- uiViewClassName: 'View',
254
+ uiViewClassName: 'RCTView',
255
}));
256
257
const snapshots = [];
@@ -272,4 +272,80 @@ describe('ReactFabric', () => {
272
);
273
expect(snapshots).toMatchSnapshot();
274
});
275
+
276
+ it('should throw when <View> is used inside of a <Text> ancestor', () => {
277
+ const Image = createReactNativeComponentClass('RCTImage', () => ({
278
+ validAttributes: {},
279
+ uiViewClassName: 'RCTImage',
280
+ }));
281
+ const Text = createReactNativeComponentClass('RCTText', () => ({
282
+ validAttributes: {},
283
+ uiViewClassName: 'RCTText',
284
+ }));
285
+ const View = createReactNativeComponentClass('RCTView', () => ({
286
+ validAttributes: {},
287
+ uiViewClassName: 'RCTView',
288
+ }));
289
+
290
+ expect(() =>
291
+ ReactFabric.render(
292
+ <Text>
293
+ <View />
294
+ </Text>,
295
+ 11,
296
+ ),
297
+ ).toThrow('Nesting of <View> within <Text> is not currently supported.');
298
+
299
+ // Non-View things (e.g. Image) are fine
300
+ ReactFabric.render(
301
+ <Text>
302
+ <Image />
303
+ </Text>,
304
+ 11,
305
+ );
306
+ });
307
+
308
+ it('should throw for text not inside of a <Text> ancestor', () => {
309
+ const ScrollView = createReactNativeComponentClass('RCTScrollView', () => ({
310
+ validAttributes: {},
311
+ uiViewClassName: 'RCTScrollView',
312
+ }));
313
+ const Text = createReactNativeComponentClass('RCTText', () => ({
314
+ validAttributes: {},
315
+ uiViewClassName: 'RCTText',
316
+ }));
317
+ const View = createReactNativeComponentClass('RCTView', () => ({
318
+ validAttributes: {},
319
+ uiViewClassName: 'RCTView',
320
+ }));
321
+
322
+ expect(() => ReactFabric.render(<View>this should warn</View>, 11)).toThrow(
323
+ 'Text strings must be rendered within a <Text> component.',
324
+ );
325
+
326
+ expect(() =>
327
+ ReactFabric.render(
328
+ <Text>
329
+ <ScrollView>hi hello hi</ScrollView>
330
+ </Text>,
331
+ 11,
332
+ ),
333
+ ).toThrow('Text strings must be rendered within a <Text> component.');
334
+ });
335
+
336
+ it('should not throw for text inside of an indirect <Text> ancestor', () => {
337
+ const Text = createReactNativeComponentClass('RCTText', () => ({
338
+ validAttributes: {},
339
+ uiViewClassName: 'RCTText',
340
+ }));
341
+
342
+ const Indirection = () => 'Hi';
343
+
344
+ ReactFabric.render(
345
+ <Text>
346
+ <Indirection />
347
+ </Text>,
348
+ 11,
349
+ );
350
+ });
351
});
packages/react-native-renderer/src/__tests__/ReactFabricAndNative-test.internal.js
+2
-2
@@ -31,9 +31,9 @@ describe('ReactFabric', () => {
31
});
32
33
it('find Fabric nodes with the RN renderer', () => {
34
- const View = createReactNativeComponentClass('View', () => ({
34
+ const View = createReactNativeComponentClass('RCTView', () => ({
35
validAttributes: {title: true},
36
- uiViewClassName: 'View',
36
+ uiViewClassName: 'RCTView',
37
}));
38
39
let ref = React.createRef();
packages/react-native-renderer/src/__tests__/ReactNativeEvents-test.internal.js
+1
-1
@@ -153,7 +153,7 @@ it('handles events', () => {
153
it('handles events on text nodes', () => {
154
expect(RCTEventEmitter.register.mock.calls.length).toBe(1);
155
const EventEmitter = RCTEventEmitter.register.mock.calls[0][0];
156
- const Text = fakeRequireNativeComponent('Text', {});
156
+ const Text = fakeRequireNativeComponent('RCTText', {});
157
158
class ContextHack extends React.Component {
159
static childContextTypes = {isInAParentText: PropTypes.bool};
packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js
+89
-13
@@ -27,9 +27,9 @@ describe('ReactNative', () => {
27
});
28
29
it('should be able to create and render a native component', () => {
30
- const View = createReactNativeComponentClass('View', () => ({
30
+ const View = createReactNativeComponentClass('RCTView', () => ({
31
validAttributes: {foo: true},
32
- uiViewClassName: 'View',
32
+ uiViewClassName: 'RCTView',
33
}));
34
35
ReactNative.render(<View foo="test" />, 1);
@@ -40,9 +40,9 @@ describe('ReactNative', () => {
40
});
41
42
it('should be able to create and update a native component', () => {
43
- const View = createReactNativeComponentClass('View', () => ({
43
+ const View = createReactNativeComponentClass('RCTView', () => ({
44
validAttributes: {foo: true},
45
- uiViewClassName: 'View',
45
+ uiViewClassName: 'RCTView',
46
}));
47
48
ReactNative.render(<View foo="foo" />, 11);
@@ -57,13 +57,13 @@ describe('ReactNative', () => {
57
expect(UIManager.createView.mock.calls.length).toBe(1);
58
expect(UIManager.setChildren.mock.calls.length).toBe(1);
59
expect(UIManager.manageChildren).not.toBeCalled();
60
- expect(UIManager.updateView).toBeCalledWith(3, 'View', {foo: 'bar'});
60
+ expect(UIManager.updateView).toBeCalledWith(3, 'RCTView', {foo: 'bar'});
61
});
62
63
it('should not call UIManager.updateView after render for properties that have not changed', () => {
64
- const Text = createReactNativeComponentClass('Text', () => ({
64
+ const Text = createReactNativeComponentClass('RCTText', () => ({
65
validAttributes: {foo: true},
66
- uiViewClassName: 'Text',
66
+ uiViewClassName: 'RCTText',
67
}));
68
69
ReactNative.render(<Text foo="a">1</Text>, 11);
@@ -87,9 +87,9 @@ describe('ReactNative', () => {
87
});
88
89
it('should not call UIManager.updateView from setNativeProps for properties that have not changed', () => {
90
- const View = createReactNativeComponentClass('View', () => ({
90
+ const View = createReactNativeComponentClass('RCTView', () => ({
91
validAttributes: {foo: true},
92
- uiViewClassName: 'View',
92
+ uiViewClassName: 'RCTView',
93
}));
94
95
class Subclass extends ReactNative.NativeComponent {
@@ -122,9 +122,9 @@ describe('ReactNative', () => {
122
});
123
124
it('returns the correct instance and calls it in the callback', () => {
125
- const View = createReactNativeComponentClass('View', () => ({
125
+ const View = createReactNativeComponentClass('RCTView', () => ({
126
validAttributes: {foo: true},
127
- uiViewClassName: 'View',
127
+ uiViewClassName: 'RCTView',
128
}));
129
130
let a;
@@ -143,9 +143,9 @@ describe('ReactNative', () => {
143
});
144
145
it('renders and reorders children', () => {
146
- const View = createReactNativeComponentClass('View', () => ({
146
+ const View = createReactNativeComponentClass('RCTView', () => ({
147
validAttributes: {title: true},
148
- uiViewClassName: 'View',
148
+ uiViewClassName: 'RCTView',
149
}));
150
151
class Component extends React.Component {
@@ -182,4 +182,80 @@ describe('ReactNative', () => {
182
ReactNative.render(<Component />, 11);
183
expect(mockArgs.length).toEqual(0);
184
});
185
+
186
+ it('should throw when <View> is used inside of a <Text> ancestor', () => {
187
+ const Image = createReactNativeComponentClass('RCTImage', () => ({
188
+ validAttributes: {},
189
+ uiViewClassName: 'RCTImage',
190
+ }));
191
+ const Text = createReactNativeComponentClass('RCTText', () => ({
192
+ validAttributes: {},
193
+ uiViewClassName: 'RCTText',
194
+ }));
195
+ const View = createReactNativeComponentClass('RCTView', () => ({
196
+ validAttributes: {},
197
+ uiViewClassName: 'RCTView',
198
+ }));
199
+
200
+ expect(() =>
201
+ ReactNative.render(
202
+ <Text>
203
+ <View />
204
+ </Text>,
205
+ 11,
206
+ ),
207
+ ).toThrow('Nesting of <View> within <Text> is not currently supported.');
208
+
209
+ // Non-View things (e.g. Image) are fine
210
+ ReactNative.render(
211
+ <Text>
212
+ <Image />
213
+ </Text>,
214
+ 11,
215
+ );
216
+ });
217
+
218
+ it('should throw for text not inside of a <Text> ancestor', () => {
219
+ const ScrollView = createReactNativeComponentClass('RCTScrollView', () => ({
220
+ validAttributes: {},
221
+ uiViewClassName: 'RCTScrollView',
222
+ }));
223
+ const Text = createReactNativeComponentClass('RCTText', () => ({
224
+ validAttributes: {},
225
+ uiViewClassName: 'RCTText',
226
+ }));
227
+ const View = createReactNativeComponentClass('RCTView', () => ({
228
+ validAttributes: {},
229
+ uiViewClassName: 'RCTView',
230
+ }));
231
+
232
+ expect(() => ReactNative.render(<View>this should warn</View>, 11)).toThrow(
233
+ 'Text strings must be rendered within a <Text> component.',
234
+ );
235
+
236
+ expect(() =>
237
+ ReactNative.render(
238
+ <Text>
239
+ <ScrollView>hi hello hi</ScrollView>
240
+ </Text>,
241
+ 11,
242
+ ),
243
+ ).toThrow('Text strings must be rendered within a <Text> component.');
244
+ });
245
+
246
+ it('should not throw for text inside of an indirect <Text> ancestor', () => {
247
+ const Text = createReactNativeComponentClass('RCTText', () => ({
248
+ validAttributes: {},
249
+ uiViewClassName: 'RCTText',
250
+ }));
251
+
252
+ const Indirection = () => 'Hi';
253
+
254
+ ReactNative.render(
255
+ <Text>
256
+ <Indirection />
257
+ </Text>,
258
+ 11,
259
+ );
260
+ });
261
});
packages/react-native-renderer/src/__tests__/__snapshots__/ReactFabric-test.internal.js.snap
+46
-46
@@ -2,69 +2,69 @@
2
3
exports[`ReactFabric renders and reorders children 1`] = `
4
"11
5
- View null
6
- View {\\"title\\":\\"a\\"}
7
- View {\\"title\\":\\"b\\"}
8
- View {\\"title\\":\\"c\\"}
9
- View {\\"title\\":\\"d\\"}
10
- View {\\"title\\":\\"e\\"}
11
- View {\\"title\\":\\"f\\"}
12
- View {\\"title\\":\\"g\\"}
13
- View {\\"title\\":\\"h\\"}
14
- View {\\"title\\":\\"i\\"}
15
- View {\\"title\\":\\"j\\"}
16
- View {\\"title\\":\\"k\\"}
17
- View {\\"title\\":\\"l\\"}
18
- View {\\"title\\":\\"m\\"}
19
- View {\\"title\\":\\"n\\"}
20
- View {\\"title\\":\\"o\\"}
21
- View {\\"title\\":\\"p\\"}
22
- View {\\"title\\":\\"q\\"}
23
- View {\\"title\\":\\"r\\"}
24
- View {\\"title\\":\\"s\\"}
25
- View {\\"title\\":\\"t\\"}"
5
+ RCTView null
6
+ RCTView {\\"title\\":\\"a\\"}
7
+ RCTView {\\"title\\":\\"b\\"}
8
+ RCTView {\\"title\\":\\"c\\"}
9
+ RCTView {\\"title\\":\\"d\\"}
10
+ RCTView {\\"title\\":\\"e\\"}
11
+ RCTView {\\"title\\":\\"f\\"}
12
+ RCTView {\\"title\\":\\"g\\"}
13
+ RCTView {\\"title\\":\\"h\\"}
14
+ RCTView {\\"title\\":\\"i\\"}
15
+ RCTView {\\"title\\":\\"j\\"}
16
+ RCTView {\\"title\\":\\"k\\"}
17
+ RCTView {\\"title\\":\\"l\\"}
18
+ RCTView {\\"title\\":\\"m\\"}
19
+ RCTView {\\"title\\":\\"n\\"}
20
+ RCTView {\\"title\\":\\"o\\"}
21
+ RCTView {\\"title\\":\\"p\\"}
22
+ RCTView {\\"title\\":\\"q\\"}
23
+ RCTView {\\"title\\":\\"r\\"}
24
+ RCTView {\\"title\\":\\"s\\"}
25
+ RCTView {\\"title\\":\\"t\\"}"
26
`;
27
28
exports[`ReactFabric renders and reorders children 2`] = `
29
"11
30
- View null
31
- View {\\"title\\":\\"m\\"}
32
- View {\\"title\\":\\"x\\"}
33
- View {\\"title\\":\\"h\\"}
34
- View {\\"title\\":\\"p\\"}
35
- View {\\"title\\":\\"g\\"}
36
- View {\\"title\\":\\"w\\"}
37
- View {\\"title\\":\\"f\\"}
38
- View {\\"title\\":\\"r\\"}
39
- View {\\"title\\":\\"a\\"}
40
- View {\\"title\\":\\"l\\"}
41
- View {\\"title\\":\\"k\\"}
42
- View {\\"title\\":\\"e\\"}
43
- View {\\"title\\":\\"o\\"}
44
- View {\\"title\\":\\"i\\"}
45
- View {\\"title\\":\\"v\\"}
46
- View {\\"title\\":\\"c\\"}
47
- View {\\"title\\":\\"s\\"}
48
- View {\\"title\\":\\"t\\"}
49
- View {\\"title\\":\\"z\\"}
50
- View {\\"title\\":\\"y\\"}"
30
+ RCTView null
31
+ RCTView {\\"title\\":\\"m\\"}
32
+ RCTView {\\"title\\":\\"x\\"}
33
+ RCTView {\\"title\\":\\"h\\"}
34
+ RCTView {\\"title\\":\\"p\\"}
35
+ RCTView {\\"title\\":\\"g\\"}
36
+ RCTView {\\"title\\":\\"w\\"}
37
+ RCTView {\\"title\\":\\"f\\"}
38
+ RCTView {\\"title\\":\\"r\\"}
39
+ RCTView {\\"title\\":\\"a\\"}
40
+ RCTView {\\"title\\":\\"l\\"}
41
+ RCTView {\\"title\\":\\"k\\"}
42
+ RCTView {\\"title\\":\\"e\\"}
43
+ RCTView {\\"title\\":\\"o\\"}
44
+ RCTView {\\"title\\":\\"i\\"}
45
+ RCTView {\\"title\\":\\"v\\"}
46
+ RCTView {\\"title\\":\\"c\\"}
47
+ RCTView {\\"title\\":\\"s\\"}
48
+ RCTView {\\"title\\":\\"t\\"}
49
+ RCTView {\\"title\\":\\"z\\"}
50
+ RCTView {\\"title\\":\\"y\\"}"
51
`;
52
53
exports[`ReactFabric should call complete after inserting children 1`] = `
54
Array [
55
- "View {\\"foo\\":\\"a\\"}
56
- View {\\"foo\\":\\"b\\"}",
55
+ "RCTView {\\"foo\\":\\"a\\"}
56
+ RCTView {\\"foo\\":\\"b\\"}",
57
]
58
`;
59
60
exports[`ReactFabric should only pass props diffs to FabricUIManager.cloneNode 1`] = `
61
"11
62
- View {\\"foo\\":\\"a\\",\\"bar\\":\\"b\\"}
62
+ RCTText {\\"foo\\":\\"a\\",\\"bar\\":\\"b\\"}
63
RCTRawText {\\"text\\":\\"1\\"}"
64
`;
65
66
exports[`ReactFabric should only pass props diffs to FabricUIManager.cloneNode 2`] = `
67
"11
68
- View {\\"foo\\":\\"b\\",\\"bar\\":\\"b\\"}
68
+ RCTText {\\"foo\\":\\"b\\",\\"bar\\":\\"b\\"}
69
RCTRawText {\\"text\\":\\"2\\"}"
70
`;
packages/react-native-renderer/src/__tests__/__snapshots__/ReactNativeMount-test.internal.js.snap
+42
-42
@@ -2,50 +2,50 @@
2
3
exports[`ReactNative renders and reorders children 1`] = `
4
"<native root> {}
5
- View null
6
- View {\\"title\\":\\"a\\"}
7
- View {\\"title\\":\\"b\\"}
8
- View {\\"title\\":\\"c\\"}
9
- View {\\"title\\":\\"d\\"}
10
- View {\\"title\\":\\"e\\"}
11
- View {\\"title\\":\\"f\\"}
12
- View {\\"title\\":\\"g\\"}
13
- View {\\"title\\":\\"h\\"}
14
- View {\\"title\\":\\"i\\"}
15
- View {\\"title\\":\\"j\\"}
16
- View {\\"title\\":\\"k\\"}
17
- View {\\"title\\":\\"l\\"}
18
- View {\\"title\\":\\"m\\"}
19
- View {\\"title\\":\\"n\\"}
20
- View {\\"title\\":\\"o\\"}
21
- View {\\"title\\":\\"p\\"}
22
- View {\\"title\\":\\"q\\"}
23
- View {\\"title\\":\\"r\\"}
24
- View {\\"title\\":\\"s\\"}
25
- View {\\"title\\":\\"t\\"}"
5
+ RCTView null
6
+ RCTView {\\"title\\":\\"a\\"}
7
+ RCTView {\\"title\\":\\"b\\"}
8
+ RCTView {\\"title\\":\\"c\\"}
9
+ RCTView {\\"title\\":\\"d\\"}
10
+ RCTView {\\"title\\":\\"e\\"}
11
+ RCTView {\\"title\\":\\"f\\"}
12
+ RCTView {\\"title\\":\\"g\\"}
13
+ RCTView {\\"title\\":\\"h\\"}
14
+ RCTView {\\"title\\":\\"i\\"}
15
+ RCTView {\\"title\\":\\"j\\"}
16
+ RCTView {\\"title\\":\\"k\\"}
17
+ RCTView {\\"title\\":\\"l\\"}
18
+ RCTView {\\"title\\":\\"m\\"}
19
+ RCTView {\\"title\\":\\"n\\"}
20
+ RCTView {\\"title\\":\\"o\\"}
21
+ RCTView {\\"title\\":\\"p\\"}
22
+ RCTView {\\"title\\":\\"q\\"}
23
+ RCTView {\\"title\\":\\"r\\"}
24
+ RCTView {\\"title\\":\\"s\\"}
25
+ RCTView {\\"title\\":\\"t\\"}"
26
`;
27
28
exports[`ReactNative renders and reorders children 2`] = `
29
"<native root> {}
30
- View null
31
- View {\\"title\\":\\"m\\"}
32
- View {\\"title\\":\\"x\\"}
33
- View {\\"title\\":\\"h\\"}
34
- View {\\"title\\":\\"p\\"}
35
- View {\\"title\\":\\"g\\"}
36
- View {\\"title\\":\\"w\\"}
37
- View {\\"title\\":\\"f\\"}
38
- View {\\"title\\":\\"r\\"}
39
- View {\\"title\\":\\"a\\"}
40
- View {\\"title\\":\\"l\\"}
41
- View {\\"title\\":\\"k\\"}
42
- View {\\"title\\":\\"e\\"}
43
- View {\\"title\\":\\"o\\"}
44
- View {\\"title\\":\\"i\\"}
45
- View {\\"title\\":\\"v\\"}
46
- View {\\"title\\":\\"c\\"}
47
- View {\\"title\\":\\"s\\"}
48
- View {\\"title\\":\\"t\\"}
49
- View {\\"title\\":\\"z\\"}
50
- View {\\"title\\":\\"y\\"}"
30
+ RCTView null
31
+ RCTView {\\"title\\":\\"m\\"}
32
+ RCTView {\\"title\\":\\"x\\"}
33
+ RCTView {\\"title\\":\\"h\\"}
34
+ RCTView {\\"title\\":\\"p\\"}
35
+ RCTView {\\"title\\":\\"g\\"}
36
+ RCTView {\\"title\\":\\"w\\"}
37
+ RCTView {\\"title\\":\\"f\\"}
38
+ RCTView {\\"title\\":\\"r\\"}
39
+ RCTView {\\"title\\":\\"a\\"}
40
+ RCTView {\\"title\\":\\"l\\"}
41
+ RCTView {\\"title\\":\\"k\\"}
42
+ RCTView {\\"title\\":\\"e\\"}
43
+ RCTView {\\"title\\":\\"o\\"}
44
+ RCTView {\\"title\\":\\"i\\"}
45
+ RCTView {\\"title\\":\\"v\\"}
46
+ RCTView {\\"title\\":\\"c\\"}
47
+ RCTView {\\"title\\":\\"s\\"}
48
+ RCTView {\\"title\\":\\"t\\"}
49
+ RCTView {\\"title\\":\\"z\\"}
50
+ RCTView {\\"title\\":\\"y\\"}"
51
`;