diff --git a/packages/events/EventPluginUtils.js b/packages/events/EventPluginUtils.js index 13e8b49c8c..33cd92a8f9 100644 --- a/packages/events/EventPluginUtils.js +++ b/packages/events/EventPluginUtils.js @@ -13,22 +13,22 @@ export let getFiberCurrentPropsFromNode = null; export let getInstanceFromNode = null; export let getNodeFromInstance = null; -export const injection = { - injectComponentTree: function(Injected) { - ({ - getFiberCurrentPropsFromNode, - getInstanceFromNode, - getNodeFromInstance, - } = Injected); - if (__DEV__) { - warningWithoutStack( - getNodeFromInstance && getInstanceFromNode, - 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + - 'module is missing getNodeFromInstance or getInstanceFromNode.', - ); - } - }, -}; +export function setComponentTree( + getFiberCurrentPropsFromNodeImpl, + getInstanceFromNodeImpl, + getNodeFromInstanceImpl, +) { + getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl; + getInstanceFromNode = getInstanceFromNodeImpl; + getNodeFromInstance = getNodeFromInstanceImpl; + if (__DEV__) { + warningWithoutStack( + getNodeFromInstance && getInstanceFromNode, + 'EventPluginUtils.setComponentTree(...): Injected ' + + 'module is missing getNodeFromInstance or getInstanceFromNode.', + ); + } +} let validateEventDispatches; if (__DEV__) { diff --git a/packages/events/ReactControlledComponent.js b/packages/events/ReactControlledComponent.js index 378125181f..bf34b29763 100644 --- a/packages/events/ReactControlledComponent.js +++ b/packages/events/ReactControlledComponent.js @@ -14,16 +14,7 @@ import { // Use to restore controlled state after a change event has fired. -let fiberHostComponent = null; - -const ReactControlledComponentInjection = { - injectFiberControlledHostComponent: function(hostComponentImpl) { - // The fiber implementation doesn't use dynamic dispatch so we need to - // inject the implementation. - fiberHostComponent = hostComponentImpl; - }, -}; - +let restoreImpl = null; let restoreTarget = null; let restoreQueue = null; @@ -36,20 +27,17 @@ function restoreStateOfTarget(target) { return; } invariant( - fiberHostComponent && - typeof fiberHostComponent.restoreControlledState === 'function', - 'Fiber needs to be injected to handle a fiber target for controlled ' + + typeof restoreImpl === 'function', + 'setRestoreImplementation() needs to be called to handle a target for controlled ' + 'events. This error is likely caused by a bug in React. Please file an issue.', ); const props = getFiberCurrentPropsFromNode(internalInstance.stateNode); - fiberHostComponent.restoreControlledState( - internalInstance.stateNode, - internalInstance.type, - props, - ); + restoreImpl(internalInstance.stateNode, internalInstance.type, props); } -export const injection = ReactControlledComponentInjection; +export function setRestoreImplementation(impl) { + restoreImpl = impl; +} export function enqueueStateRestore(target) { if (restoreTarget) { diff --git a/packages/events/ReactGenericBatching.js b/packages/events/ReactGenericBatching.js index 96a9bd9a51..5d18e1b716 100644 --- a/packages/events/ReactGenericBatching.js +++ b/packages/events/ReactGenericBatching.js @@ -17,13 +17,13 @@ import { // scheduled work and instead do synchronous work. // Defaults -let _batchedUpdates = function(fn, bookkeeping) { +let _batchedUpdatesImpl = function(fn, bookkeeping) { return fn(bookkeeping); }; -let _interactiveUpdates = function(fn, a, b) { +let _interactiveUpdatesImpl = function(fn, a, b) { return fn(a, b); }; -let _flushInteractiveUpdates = function() {}; +let _flushInteractiveUpdatesImpl = function() {}; let isBatching = false; export function batchedUpdates(fn, bookkeeping) { @@ -34,7 +34,7 @@ export function batchedUpdates(fn, bookkeeping) { } isBatching = true; try { - return _batchedUpdates(fn, bookkeeping); + return _batchedUpdatesImpl(fn, bookkeeping); } finally { // Here we wait until all updates have propagated, which is important // when using controlled components within layers: @@ -46,24 +46,26 @@ export function batchedUpdates(fn, bookkeeping) { // If a controlled event was fired, we may need to restore the state of // the DOM node back to the controlled value. This is necessary when React // bails out of the update without touching the DOM. - _flushInteractiveUpdates(); + _flushInteractiveUpdatesImpl(); restoreStateIfNeeded(); } } } export function interactiveUpdates(fn, a, b) { - return _interactiveUpdates(fn, a, b); + return _interactiveUpdatesImpl(fn, a, b); } export function flushInteractiveUpdates() { - return _flushInteractiveUpdates(); + return _flushInteractiveUpdatesImpl(); } -export const injection = { - injectRenderer(renderer) { - _batchedUpdates = renderer.batchedUpdates; - _interactiveUpdates = renderer.interactiveUpdates; - _flushInteractiveUpdates = renderer.flushInteractiveUpdates; - }, -}; +export function setBatchingImplementation( + batchedUpdatesImpl, + interactiveUpdatesImpl, + flushInteractiveUpdatesImpl, +) { + _batchedUpdatesImpl = batchedUpdatesImpl; + _interactiveUpdatesImpl = interactiveUpdatesImpl; + _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl; +} diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index 8a179d1e55..ea887f774c 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -36,7 +36,7 @@ import lowPriorityWarning from 'shared/lowPriorityWarning'; import warningWithoutStack from 'shared/warningWithoutStack'; import * as ReactDOMComponentTree from './ReactDOMComponentTree'; -import * as ReactDOMFiberComponent from './ReactDOMFiberComponent'; +import {restoreControlledState} from './ReactDOMFiberComponent'; import * as ReactDOMEventListener from '../events/ReactDOMEventListener'; import { ELEMENT_NODE, @@ -124,9 +124,7 @@ if (__DEV__) { }; } -ReactControlledComponent.injection.injectFiberControlledHostComponent( - ReactDOMFiberComponent, -); +ReactControlledComponent.setRestoreImplementation(restoreControlledState); type DOMContainer = | (Element & { @@ -450,7 +448,11 @@ function shouldHydrateDueToLegacyHeuristic(container) { ); } -ReactGenericBatching.injection.injectRenderer(DOMRenderer); +ReactGenericBatching.setBatchingImplementation( + DOMRenderer.batchedUpdates, + DOMRenderer.interactiveUpdates, + DOMRenderer.flushInteractiveUpdates, +); let warnedAboutHydrateAPI = false; diff --git a/packages/react-dom/src/client/ReactDOMClientInjection.js b/packages/react-dom/src/client/ReactDOMClientInjection.js index 10b3c00eeb..4ddc72716c 100644 --- a/packages/react-dom/src/client/ReactDOMClientInjection.js +++ b/packages/react-dom/src/client/ReactDOMClientInjection.js @@ -8,7 +8,11 @@ import * as EventPluginHub from 'events/EventPluginHub'; import * as EventPluginUtils from 'events/EventPluginUtils'; -import * as ReactDOMComponentTree from './ReactDOMComponentTree'; +import { + getFiberCurrentPropsFromNode, + getInstanceFromNode, + getNodeFromInstance, +} from './ReactDOMComponentTree'; import BeforeInputEventPlugin from '../events/BeforeInputEventPlugin'; import ChangeEventPlugin from '../events/ChangeEventPlugin'; import DOMEventPluginOrder from '../events/DOMEventPluginOrder'; @@ -20,7 +24,11 @@ import SimpleEventPlugin from '../events/SimpleEventPlugin'; * Inject modules for resolving DOM hierarchy and plugin ordering. */ EventPluginHub.injection.injectEventPluginOrder(DOMEventPluginOrder); -EventPluginUtils.injection.injectComponentTree(ReactDOMComponentTree); +EventPluginUtils.setComponentTree( + getFiberCurrentPropsFromNode, + getInstanceFromNode, + getNodeFromInstance, +); /** * Some important event plugins included by default (without having to require diff --git a/packages/react-dom/src/client/ReactDOMHostConfig.js b/packages/react-dom/src/client/ReactDOMHostConfig.js index 0b3d930a4b..8da30eacc4 100644 --- a/packages/react-dom/src/client/ReactDOMHostConfig.js +++ b/packages/react-dom/src/client/ReactDOMHostConfig.js @@ -7,10 +7,21 @@ * @flow */ -import * as ReactScheduler from 'shared/ReactScheduler'; - -import * as ReactDOMComponentTree from './ReactDOMComponentTree'; -import * as ReactDOMFiberComponent from './ReactDOMFiberComponent'; +import {precacheFiberNode, updateFiberProps} from './ReactDOMComponentTree'; +import { + createElement, + createTextNode, + setInitialProperties, + diffProperties, + updateProperties, + diffHydratedProperties, + diffHydratedText, + warnForUnmatchedText, + warnForDeletedHydratableElement, + warnForDeletedHydratableText, + warnForInsertedHydratedElement, + warnForInsertedHydratedText, +} from './ReactDOMFiberComponent'; import * as ReactInputSelection from './ReactInputSelection'; import setTextContent from './setTextContent'; import {validateDOMNesting, updatedAncestorInfo} from './validateDOMNesting'; @@ -48,21 +59,11 @@ export type ChildSet = void; // Unused export type TimeoutHandle = TimeoutID; export type NoTimeout = -1; -const { - createElement, - createTextNode, - setInitialProperties, - diffProperties, - updateProperties, - diffHydratedProperties, - diffHydratedText, - warnForUnmatchedText, - warnForDeletedHydratableElement, - warnForDeletedHydratableText, - warnForInsertedHydratedElement, - warnForInsertedHydratedText, -} = ReactDOMFiberComponent; -const {precacheFiberNode, updateFiberProps} = ReactDOMComponentTree; +export { + now, + scheduleWork as scheduleDeferredCallback, + cancelScheduledWork as cancelDeferredCallback, +} from 'shared/ReactScheduler'; let SUPPRESS_HYDRATION_WARNING; if (__DEV__) { @@ -272,11 +273,7 @@ export function createTextInstance( return textNode; } -export const now = ReactScheduler.now; export const isPrimaryRenderer = true; -export const scheduleDeferredCallback = ReactScheduler.scheduleWork; -export const cancelDeferredCallback = ReactScheduler.cancelScheduledWork; - export const scheduleTimeout = setTimeout; export const cancelTimeout = clearTimeout; export const noTimeout = -1; diff --git a/packages/react-dom/src/unstable-native-dependencies/ReactDOMUnstableNativeDependencies.js b/packages/react-dom/src/unstable-native-dependencies/ReactDOMUnstableNativeDependencies.js index 763a4f38d0..63f429b6d0 100644 --- a/packages/react-dom/src/unstable-native-dependencies/ReactDOMUnstableNativeDependencies.js +++ b/packages/react-dom/src/unstable-native-dependencies/ReactDOMUnstableNativeDependencies.js @@ -11,12 +11,22 @@ import ResponderEventPlugin from 'events/ResponderEventPlugin'; import ResponderTouchHistoryStore from 'events/ResponderTouchHistoryStore'; // This is used by react-native-web. -export const injectComponentTree = - EventPluginUtils.injection.injectComponentTree; +export function injectComponentTree(ComponentTree) { + EventPluginUtils.setComponentTree( + ComponentTree.getFiberCurrentPropsFromNode, + ComponentTree.getInstanceFromNode, + ComponentTree.getNodeFromInstance, + ); +} + export {ResponderEventPlugin, ResponderTouchHistoryStore}; // Inject react-dom's ComponentTree into this module. const { ReactDOMComponentTree, } = ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; -injectComponentTree(ReactDOMComponentTree); +EventPluginUtils.setComponentTree( + ReactDOMComponentTree.getFiberCurrentPropsFromNode, + ReactDOMComponentTree.getInstanceFromNode, + ReactDOMComponentTree.getNodeFromInstance, +); diff --git a/packages/react-native-renderer/src/ReactFabric.js b/packages/react-native-renderer/src/ReactFabric.js index 8963ae4d46..8c611d5419 100644 --- a/packages/react-native-renderer/src/ReactFabric.js +++ b/packages/react-native-renderer/src/ReactFabric.js @@ -73,7 +73,11 @@ function findNodeHandle(componentOrHandle: any): ?number { return hostInstance._nativeTag; } -ReactGenericBatching.injection.injectRenderer(ReactFabricRenderer); +ReactGenericBatching.setBatchingImplementation( + ReactFabricRenderer.batchedUpdates, + ReactFabricRenderer.interactiveUpdates, + ReactFabricRenderer.flushInteractiveUpdates, +); const roots = new Map(); diff --git a/packages/react-native-renderer/src/ReactFabricInjection.js b/packages/react-native-renderer/src/ReactFabricInjection.js index 492a8cd29d..d50c482399 100644 --- a/packages/react-native-renderer/src/ReactFabricInjection.js +++ b/packages/react-native-renderer/src/ReactFabricInjection.js @@ -14,7 +14,11 @@ import * as EventPluginUtils from 'events/EventPluginUtils'; import ReactFabricGlobalResponderHandler from './ReactFabricGlobalResponderHandler'; import ResponderEventPlugin from 'events/ResponderEventPlugin'; -EventPluginUtils.injection.injectComponentTree(ReactFabricComponentTree); +EventPluginUtils.setComponentTree( + ReactFabricComponentTree.getFiberCurrentPropsFromNode, + ReactFabricComponentTree.getInstanceFromNode, + ReactFabricComponentTree.getNodeFromInstance, +); ResponderEventPlugin.injection.injectGlobalResponderHandler( ReactFabricGlobalResponderHandler, diff --git a/packages/react-native-renderer/src/ReactNativeInjection.js b/packages/react-native-renderer/src/ReactNativeInjection.js index 5fea3d78cb..8fabbc57d5 100644 --- a/packages/react-native-renderer/src/ReactNativeInjection.js +++ b/packages/react-native-renderer/src/ReactNativeInjection.js @@ -23,7 +23,11 @@ import RCTEventEmitter from 'RCTEventEmitter'; */ RCTEventEmitter.register(ReactNativeEventEmitter); -EventPluginUtils.injection.injectComponentTree(ReactNativeComponentTree); +EventPluginUtils.setComponentTree( + ReactNativeComponentTree.getFiberCurrentPropsFromNode, + ReactNativeComponentTree.getInstanceFromNode, + ReactNativeComponentTree.getNodeFromInstance, +); ResponderEventPlugin.injection.injectGlobalResponderHandler( ReactNativeGlobalResponderHandler, diff --git a/packages/react-native-renderer/src/ReactNativeRenderer.js b/packages/react-native-renderer/src/ReactNativeRenderer.js index 803d5e0257..fc1ffbe431 100644 --- a/packages/react-native-renderer/src/ReactNativeRenderer.js +++ b/packages/react-native-renderer/src/ReactNativeRenderer.js @@ -74,7 +74,11 @@ function findNodeHandle(componentOrHandle: any): ?number { return hostInstance._nativeTag; } -ReactGenericBatching.injection.injectRenderer(ReactNativeFiberRenderer); +ReactGenericBatching.setBatchingImplementation( + ReactNativeFiberRenderer.batchedUpdates, + ReactNativeFiberRenderer.interactiveUpdates, + ReactNativeFiberRenderer.flushInteractiveUpdates, +); function computeComponentStackForErrorReporting(reactTag: number): string { let fiber = ReactNativeComponentTree.getClosestInstanceFromNode(reactTag);