Rework ReactRootIndex generation
This had a higher probability of collision than originally thought (bad math). This makes the strategy injectable and provies a no-collision version on the client and an unlikely-to-collide version on the server.
Pete Hunt committed
Jan 2, 2014 at 18:28 UTC
1733d42ded7d002afe1c4d3969855fd13b6376a9
5 files changed
+120
-12
src/core/ReactDefaultInjection.js
+11
@@ -18,6 +18,8 @@
18
19
"use strict";
20
21
+var ExecutionEnvironment = require('ExecutionEnvironment');
22
+
23
var ReactDOM = require('ReactDOM');
24
var ReactDOMButton = require('ReactDOMButton');
25
var ReactDOMForm = require('ReactDOMForm');
@@ -28,11 +30,13 @@ var ReactDOMTextarea = require('ReactDOMTextarea');
30
var ReactEventEmitter = require('ReactEventEmitter');
31
var ReactEventTopLevelCallback = require('ReactEventTopLevelCallback');
32
var ReactPerf = require('ReactPerf');
33
+var ReactRootIndex = require('ReactRootIndex');
34
35
var DefaultDOMPropertyConfig = require('DefaultDOMPropertyConfig');
36
var DOMProperty = require('DOMProperty');
37
38
var ChangeEventPlugin = require('ChangeEventPlugin');
39
+var ClientReactRootIndex = require('ClientReactRootIndex');
40
var CompositionEventPlugin = require('CompositionEventPlugin');
41
var DefaultEventPluginOrder = require('DefaultEventPluginOrder');
42
var EnterLeaveEventPlugin = require('EnterLeaveEventPlugin');
@@ -40,6 +44,7 @@ var EventPluginHub = require('EventPluginHub');
44
var MobileSafariClickEventPlugin = require('MobileSafariClickEventPlugin');
45
var ReactInstanceHandles = require('ReactInstanceHandles');
46
var SelectEventPlugin = require('SelectEventPlugin');
47
+var ServerReactRootIndex = require('ServerReactRootIndex');
48
var SimpleEventPlugin = require('SimpleEventPlugin');
49
50
var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');
@@ -84,6 +89,12 @@ function inject() {
89
ReactUpdates.injection.injectBatchingStrategy(
90
ReactDefaultBatchingStrategy
91
);
92
+
93
+ ReactRootIndex.injection.injectCreateReactRootIndex(
94
+ ExecutionEnvironment.canUseDOM ?
95
+ ClientReactRootIndex.createReactRootIndex :
96
+ ServerReactRootIndex.createReactRootIndex
97
+ );
98
}
99
100
module.exports = {
src/core/ReactInstanceHandles.js
+7
-12
@@ -19,6 +19,8 @@
19
20
"use strict";
21
22
+var ReactRootIndex = require('ReactRootIndex');
23
+
24
var invariant = require('invariant');
25
26
var SEPARATOR = '.';
@@ -29,15 +31,6 @@ var SEPARATOR_LENGTH = SEPARATOR.length;
31
*/
32
var MAX_TREE_DEPTH = 100;
33
32
-/**
33
- * Size of the reactRoot ID space. We generate random numbers for React root
34
- * IDs and if there's a collision the events and DOM update system will
35
- * get confused. If we assume 100 React components per page, and a user
36
- * loads 1 page per minute 24/7 for 50 years, with a mount point space of
37
- * 9,999,999 the likelihood of never having a collision is 99.997%.
38
- */
39
-var GLOBAL_MOUNT_POINT_MAX = 9999999;
40
-
34
/**
35
* Creates a DOM ID prefix to use when mounting React components.
36
*
@@ -229,10 +222,12 @@ function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) {
222
*/
223
var ReactInstanceHandles = {
224
225
+ /**
226
+ * Constructs a React root ID
227
+ * @return {string} A React root ID.
228
+ */
229
createReactRootID: function() {
233
- return getReactRootIDString(
234
- Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX)
235
- );
230
+ return getReactRootIDString(ReactRootIndex.createReactRootIndex());
231
},
232
233
/**
src/core/ReactRootIndex.js
new
+36
@@ -0,0 +1,36 @@
1
+/**
2
+ * Copyright 2013 Facebook, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @providesModule ReactRootIndex
17
+ * @typechecks
18
+ */
19
+
20
+"use strict";
21
+
22
+var ReactRootIndexInjection = {
23
+ /**
24
+ * @param {function} _createReactRootIndex
25
+ */
26
+ injectCreateReactRootIndex: function(_createReactRootIndex) {
27
+ ReactRootIndex.createReactRootIndex = _createReactRootIndex;
28
+ }
29
+};
30
+
31
+var ReactRootIndex = {
32
+ createReactRootIndex: null,
33
+ injection: ReactRootIndexInjection
34
+};
35
+
36
+module.exports = ReactRootIndex;
src/environment/ClientReactRootIndex.js
new
+30
@@ -0,0 +1,30 @@
1
+/**
2
+ * Copyright 2013 Facebook, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @providesModule ClientReactRootIndex
17
+ * @typechecks
18
+ */
19
+
20
+"use strict";
21
+
22
+var nextReactRootIndex = 0;
23
+
24
+var ClientReactRootIndex = {
25
+ createReactRootIndex: function() {
26
+ return nextReactRootIndex++;
27
+ }
28
+};
29
+
30
+module.exports = ClientReactRootIndex;
src/environment/ServerReactRootIndex.js
new
+36
@@ -0,0 +1,36 @@
1
+/**
2
+ * Copyright 2013 Facebook, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @providesModule ServerReactRootIndex
17
+ * @typechecks
18
+ */
19
+
20
+"use strict";
21
+
22
+/**
23
+ * Size of the reactRoot ID space. We generate random numbers for React root
24
+ * IDs and if there's a collision the events and DOM update system will
25
+ * get confused. In the future we need a way to generate GUIDs but for
26
+ * now this will work on a smaller scale.
27
+ */
28
+var GLOBAL_MOUNT_POINT_MAX = Math.pow(2, 53);
29
+
30
+var ServerReactRootIndex = {
31
+ createReactRootIndex: function() {
32
+ return Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX);
33
+ }
34
+};
35
+
36
+module.exports = ServerReactRootIndex;