@samitouri / QOS-React-2 / commits / 1733d42ded

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;