@samitouri / QOS-React / commits / ea47782aaa

Create ReactGenericBatching injection wrapper around BatchedUpdates

This moves calls that don't know if they're in a Fiber or Stack context to use ReactGenericBatching.batchedUpdates. The corresponding one will be injected from either the stack reconciler and/or the fiber reconciler if they're loaded at the same time. This lets them share the event system when they're both used at once. This can also be useful for libraries that call unstable_batchedUpdates today but don't know which renderer to use.

Sebastian Markbage committed Oct 27, 2016 at 18:57 UTC ea47782aaac8b405c21f0192b7a23b9820e5ace7
6 files changed +69 -6
src/renderers/dom/shared/ReactEventListener.js
+2 -2
@@ -15,7 +15,7 @@ var EventListener = require('EventListener');
15 var ExecutionEnvironment = require('ExecutionEnvironment');
16 var PooledClass = require('PooledClass');
17 var ReactDOMComponentTree = require('ReactDOMComponentTree');
18 -var ReactUpdates = require('ReactUpdates');
18 +var ReactGenericBatching = require('ReactGenericBatching');
19
20 var getEventTarget = require('getEventTarget');
21 var getUnboundedScrollPosition = require('getUnboundedScrollPosition');
@@ -165,7 +165,7 @@ var ReactEventListener = {
165 try {
166 // Event queue being processed in the same cycle allows
167 // `preventDefault`.
168 - ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);
168 + ReactGenericBatching.batchedUpdates(handleTopLevelImpl, bookKeeping);
169 } finally {
170 TopLevelCallbackBookKeeping.release(bookKeeping);
171 }
src/renderers/dom/shared/eventPlugins/ChangeEventPlugin.js
+2 -2
@@ -15,7 +15,7 @@ var EventPluginHub = require('EventPluginHub');
15 var EventPropagators = require('EventPropagators');
16 var ExecutionEnvironment = require('ExecutionEnvironment');
17 var ReactDOMComponentTree = require('ReactDOMComponentTree');
18 -var ReactUpdates = require('ReactUpdates');
18 +var ReactGenericBatching = require('ReactGenericBatching');
19 var SyntheticEvent = require('SyntheticEvent');
20
21 var inputValueTracking = require('inputValueTracking');
@@ -98,7 +98,7 @@ function manualDispatchChangeEvent(nativeEvent) {
98 // components don't work properly in conjunction with event bubbling because
99 // the component is rerendered and the value reverted before all the event
100 // handlers can run. See https://github.com/facebook/react/issues/708.
101 - ReactUpdates.batchedUpdates(runEventInBatch, event);
101 + ReactGenericBatching.batchedUpdates(runEventInBatch, event);
102 }
103
104 function runEventInBatch(event) {
src/renderers/dom/stack/client/ReactDOMStackInjection.js
+5
@@ -19,6 +19,7 @@ var ReactDOMEmptyComponent = require('ReactDOMEmptyComponent');
19 var ReactDOMTextComponent = require('ReactDOMTextComponent');
20 var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');
21 var ReactEmptyComponent = require('ReactEmptyComponent');
22 +var ReactGenericBatching = require('ReactGenericBatching');
23 var ReactHostComponent = require('ReactHostComponent');
24 var ReactReconcileTransaction = require('ReactReconcileTransaction');
25 var ReactUpdates = require('ReactUpdates');
@@ -34,6 +35,10 @@ function inject() {
35 }
36 alreadyInjected = true;
37
38 + ReactGenericBatching.injection.injectStackBatchedUpdates(
39 + ReactUpdates.batchedUpdates
40 + );
41 +
42 ReactHostComponent.injection.injectGenericComponentClass(
43 ReactDOMComponent
44 );
src/renderers/native/ReactNativeEventEmitter.js
+2 -2
@@ -16,7 +16,7 @@ var EventPluginRegistry = require('EventPluginRegistry');
16 var ReactEventEmitterMixin = require('ReactEventEmitterMixin');
17 var ReactNativeComponentTree = require('ReactNativeComponentTree');
18 var ReactNativeTagHandles = require('ReactNativeTagHandles');
19 -var ReactUpdates = require('ReactUpdates');
19 +var ReactGenericBatching = require('ReactGenericBatching');
20
21 var warning = require('warning');
22
@@ -123,7 +123,7 @@ var ReactNativeEventEmitter = {
123 // any events.
124 return;
125 }
126 - ReactUpdates.batchedUpdates(function() {
126 + ReactGenericBatching.batchedUpdates(function() {
127 ReactNativeEventEmitter.handleTopLevel(
128 topLevelType,
129 inst,
src/renderers/native/ReactNativeStackInjection.js
+5
@@ -23,6 +23,7 @@ var React = require('React');
23 var ReactComponentEnvironment = require('ReactComponentEnvironment');
24 var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');
25 var ReactEmptyComponent = require('ReactEmptyComponent');
26 +var ReactGenericBatching = require('ReactGenericBatching');
27 var ReactHostComponent = require('ReactHostComponent');
28 var ReactNativeComponentEnvironment = require('ReactNativeComponentEnvironment');
29 var ReactNativeTextComponent = require('ReactNativeTextComponent');
@@ -32,6 +33,10 @@ var ReactUpdates = require('ReactUpdates');
33 var invariant = require('invariant');
34
35 function inject() {
36 + ReactGenericBatching.injection.injectStackBatchedUpdates(
37 + ReactUpdates.batchedUpdates
38 + );
39 +
40 ReactUpdates.injection.injectReconcileTransaction(
41 ReactNativeComponentEnvironment.ReactReconcileTransaction
42 );
src/renderers/shared/shared/event/ReactGenericBatching.js new
+53
@@ -0,0 +1,53 @@
1 +/**
2 + * Copyright 2013-present, Facebook, Inc.
3 + * All rights reserved.
4 + *
5 + * This source code is licensed under the BSD-style license found in the
6 + * LICENSE file in the root directory of this source tree. An additional grant
7 + * of patent rights can be found in the PATENTS file in the same directory.
8 + *
9 + * @providesModule ReactGenericBatching
10 + */
11 +
12 +'use strict';
13 +
14 +// Used as a way to call batchedUpdates when we don't know if we're in a Fiber
15 +// or Stack context. Such as when we're dispatching events or if third party
16 +// libraries need to call batchedUpdates. Eventually, this API will go away when
17 +// everything is batched by default. We'll then have a similar API to opt-out of
18 +// scheduled work and instead do synchronous work.
19 +
20 +// Defaults
21 +var stackBatchedUpdates = function(fn, a, b, c, d, e) {
22 + fn(a, b, c, d, e);
23 +};
24 +var fiberPerformSynchronousWork = function(fn, bookkeeping) {
25 + fn(bookkeeping);
26 +};
27 +
28 +function performFiberBatchedUpdates(fn, bookkeeping) {
29 + // If we have Fiber loaded, we need to wrap this in a batching call so that
30 + // Fiber can apply its default priority for this call.
31 + fiberPerformSynchronousWork(fn, bookkeeping);
32 +}
33 +function batchedUpdates(fn, bookkeeping) {
34 + // We first perform work with the stack batching strategy, by passing our
35 + // indirection to it.
36 + stackBatchedUpdates(performFiberBatchedUpdates, fn, bookkeeping);
37 +}
38 +
39 +var ReactGenericBatchingInjection = {
40 + injectStackBatchedUpdates: function(_batchedUpdates) {
41 + stackBatchedUpdates = _batchedUpdates;
42 + },
43 + injectFiberPerformSynchronousWork: function(_performSynchronousWork) {
44 + fiberPerformSynchronousWork = _performSynchronousWork;
45 + },
46 +};
47 +
48 +var ReactGenericBatching = {
49 + batchedUpdates,
50 + injection: ReactGenericBatchingInjection,
51 +};
52 +
53 +module.exports = ReactGenericBatching;