Skip to content

Commit 2f7bca0

Browse files
authored
Allocate unique reactTags for RN and Fabric (#12587)
Took this opportunity to remove some abstract overhead. In Fabric it is extra simple since they no longer overlap with root tags.
1 parent f88deda commit 2f7bca0

File tree

6 files changed

+29
-65
lines changed

6 files changed

+29
-65
lines changed

packages/react-native-renderer/src/ReactFabricRenderer.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import * as ReactNativeAttributePayload from './ReactNativeAttributePayload';
2020
import * as ReactNativeFrameScheduling from './ReactNativeFrameScheduling';
2121
import * as ReactNativeViewConfigRegistry from './ReactNativeViewConfigRegistry';
2222
import ReactFiberReconciler from 'react-reconciler';
23-
import ReactNativeTagHandles from './ReactNativeTagHandles';
2423

2524
import deepFreezeAndThrowOnMutationInDev from 'deepFreezeAndThrowOnMutationInDev';
2625
import emptyObject from 'fbjs/lib/emptyObject';
@@ -30,6 +29,12 @@ import TextInputState from 'TextInputState';
3029
import FabricUIManager from 'FabricUIManager';
3130
import UIManager from 'UIManager';
3231

32+
// Counter for uniquely identifying views.
33+
// % 10 === 1 means it is a rootTag.
34+
// % 2 === 0 means it is a Fabric tag.
35+
// This means that they never overlap.
36+
let nextReactTag = 2;
37+
3338
/**
3439
* This is used for refs on host components.
3540
*/
@@ -133,7 +138,9 @@ const ReactFabricRenderer = ReactFiberReconciler({
133138
hostContext: {},
134139
internalInstanceHandle: Object,
135140
): Instance {
136-
const tag = ReactNativeTagHandles.allocateTag();
141+
const tag = nextReactTag;
142+
nextReactTag += 2;
143+
137144
const viewConfig = ReactNativeViewConfigRegistry.get(type);
138145

139146
if (__DEV__) {
@@ -171,7 +178,8 @@ const ReactFabricRenderer = ReactFiberReconciler({
171178
hostContext: {},
172179
internalInstanceHandle: Object,
173180
): TextInstance {
174-
const tag = ReactNativeTagHandles.allocateTag();
181+
const tag = nextReactTag;
182+
nextReactTag += 2;
175183

176184
const node = FabricUIManager.createNode(
177185
tag, // reactTag

packages/react-native-renderer/src/ReactNativeEventEmitter.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {batchedUpdates} from 'events/ReactGenericBatching';
1313
import warning from 'fbjs/lib/warning';
1414

1515
import {getInstanceFromNode} from './ReactNativeComponentTree';
16-
import ReactNativeTagHandles from './ReactNativeTagHandles';
1716

1817
import type {AnyNativeEvent} from 'events/PluginModuleType';
1918

@@ -166,7 +165,7 @@ export function receiveTouches(
166165
let rootNodeID = null;
167166
const target = nativeEvent.target;
168167
if (target !== null && target !== undefined) {
169-
if (target < ReactNativeTagHandles.tagsStartAt) {
168+
if (target < 1) {
170169
if (__DEV__) {
171170
warning(
172171
false,

packages/react-native-renderer/src/ReactNativeFiberRenderer.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import {
2525
} from './ReactNativeComponentTree';
2626
import ReactNativeFiberHostComponent from './ReactNativeFiberHostComponent';
2727
import * as ReactNativeFrameScheduling from './ReactNativeFrameScheduling';
28-
import ReactNativeTagHandles from './ReactNativeTagHandles';
2928

3029
type Container = number;
3130
export type Instance = {
@@ -36,6 +35,19 @@ export type Instance = {
3635
type Props = Object;
3736
type TextInstance = number;
3837

38+
// Counter for uniquely identifying views.
39+
// % 10 === 1 means it is a rootTag.
40+
// % 2 === 0 means it is a Fabric tag.
41+
let nextReactTag = 3;
42+
function allocateTag() {
43+
let tag = nextReactTag;
44+
if (tag % 10 === 1) {
45+
tag += 2;
46+
}
47+
nextReactTag = tag + 2;
48+
return tag;
49+
}
50+
3951
function recursivelyUncacheFiberNode(node: Instance | TextInstance) {
4052
if (typeof node === 'number') {
4153
// Leaf node (eg text)
@@ -62,7 +74,7 @@ const NativeRenderer = ReactFiberReconciler({
6274
hostContext: {},
6375
internalInstanceHandle: Object,
6476
): Instance {
65-
const tag = ReactNativeTagHandles.allocateTag();
77+
const tag = allocateTag();
6678
const viewConfig = ReactNativeViewConfigRegistry.get(type);
6779

6880
if (__DEV__) {
@@ -101,7 +113,7 @@ const NativeRenderer = ReactFiberReconciler({
101113
hostContext: {},
102114
internalInstanceHandle: Object,
103115
): TextInstance {
104-
const tag = ReactNativeTagHandles.allocateTag();
116+
const tag = allocateTag();
105117

106118
UIManager.createView(
107119
tag, // reactTag

packages/react-native-renderer/src/ReactNativeTagHandles.js

Lines changed: 0 additions & 54 deletions
This file was deleted.

packages/react-native-renderer/src/__mocks__/UIManager.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
// Mock of the Native Hooks
1111

12-
const ReactNativeTagHandles = require('../ReactNativeTagHandles').default;
1312
const invariant = require('fbjs/lib/invariant');
1413

1514
// Map of viewTag -> {children: [childTag], parent: ?parentTag}
@@ -18,7 +17,7 @@ let views = new Map();
1817

1918
function autoCreateRoot(tag) {
2019
// Seriously, this is how we distinguish roots in RN.
21-
if (!views.has(tag) && ReactNativeTagHandles.reactTagIsNativeTopRootID(tag)) {
20+
if (!views.has(tag) && tag % 10 === 1) {
2221
roots.push(tag);
2322
views.set(tag, {
2423
children: [],

packages/react-native-renderer/src/__tests__/ReactNativeMount-test.internal.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ describe('ReactNative', () => {
5757
expect(UIManager.createView.mock.calls.length).toBe(1);
5858
expect(UIManager.setChildren.mock.calls.length).toBe(1);
5959
expect(UIManager.manageChildren).not.toBeCalled();
60-
expect(UIManager.updateView).toBeCalledWith(2, 'View', {foo: 'bar'});
60+
expect(UIManager.updateView).toBeCalledWith(3, 'View', {foo: 'bar'});
6161
});
6262

6363
it('should not call UIManager.updateView after render for properties that have not changed', () => {

0 commit comments

Comments
 (0)