Files
react/src/renderers/native/ReactNativeFiber.js
Brian Vaughn c22b94f14a ReactNative flat renderer bundles (#9626)
* Split ReactNativeFiber into separate ReactNativeFiberRenderer module
Hopefully this is sufficient to work around Rollup circular dependency problems. (To be seen in subsequent commits...)

* Split findNodeHandle into findNodeHandleFiber + findNodeHandleStack
This allowed me to remove the ReactNative -> findNodeHandle injections, which should in turn allow me to require a fully-functional findNodeHandle without going through ReactNative. This will hopefully allow ReactNativeBaseomponent to avoid a circular dependency.

* Un-forked findNodeHandle in favor of just inlining the findNode function impl

* takeSnapshot no longer requires/depends-on ReactNative for findNodeHandle
Instead it uses the new, renderer-specific wrappers (eg findNodeHandleFiberWrapper and findNodeHandleStackWrapper) to ensure the returned value is numeric (or null). This avoids a circular dependency that would trip up Rollup.

* NativeMethodsMixin requires findNodeHandler wrapper(s) directly rather than ReactNative
This works around a potential circular dependency that would break the Rollup build

* Add RN_* build targets to hash-finle-name check

* Strip @providesModule annotations from headers for RN_* builds

* Added process.env.REACT_NATIVE_USE_FIBER to ReactNativeFeatureFlags
This is kind of a hacky solution, but it is temporary. It works around the fact that ReactNativeFeatureFlag values need to be set at build time in order to avoid a mismatch between runtime flag values. DOM avoids the need to do this by using injection but Native is not able to use this same approach due to circular dependency issues.

* Moved a couple of SECRET exports to dev-only. Removed SyntheticEvent and PooledClass from SECRET exports. Converted Rollup helper function to use named params.

* Split NativeMethodsMixins interface and object-type

* Add @noflow header to flat-bundle template to avoid triggering Flow problems
When Flow tries to infer such a large file, it consumes massive amounts of CPU/RAM and can often lead to programs crashing. It is better for such large files to use .flow.js types instead.

* NativeMethodsMixin and ReactNativeFiberHostComponent now share the same Flow type

* Collocated (externally exposed) ReactTypes and ReactNativeTypes into single files to be synced to fbsource. ReactNativeFiber and ReactNativeStack use ReactNativeType Flow type

* Build script syncs RN types and PooledClass automatically

* Added optional sync-RN step to Rollup build script

* Added results.json for new RN bundles
2017-05-24 17:06:30 +01:00

129 lines
4.5 KiB
JavaScript

/**
* Copyright 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule ReactNativeFiber
* @flow
*/
'use strict';
const ReactFiberErrorLogger = require('ReactFiberErrorLogger');
const ReactGenericBatching = require('ReactGenericBatching');
const ReactNativeFiberErrorDialog = require('ReactNativeFiberErrorDialog');
const ReactNativeInjection = require('ReactNativeInjection');
const ReactPortal = require('ReactPortal');
const ReactNativeComponentTree = require('ReactNativeComponentTree');
const ReactNativeFiberRenderer = require('ReactNativeFiberRenderer');
const ReactNativeFiberInspector = require('ReactNativeFiberInspector');
const ReactVersion = require('ReactVersion');
const UIManager = require('UIManager');
const findNumericNodeHandle = require('findNumericNodeHandleFiber');
const {injectInternals} = require('ReactFiberDevToolsHook');
import type {Element} from 'React';
import type {ReactNativeType} from 'ReactNativeTypes';
import type {ReactNodeList} from 'ReactTypes';
ReactNativeInjection.inject();
ReactGenericBatching.injection.injectFiberBatchedUpdates(
ReactNativeFiberRenderer.batchedUpdates,
);
const roots = new Map();
// Intercept lifecycle errors and ensure they are shown with the correct stack
// trace within the native redbox component.
ReactFiberErrorLogger.injection.injectDialog(
ReactNativeFiberErrorDialog.showDialog,
);
var ReactNative: ReactNativeType = {
findNodeHandle: findNumericNodeHandle,
render(element: Element<any>, containerTag: any, callback: ?Function) {
let root = roots.get(containerTag);
if (!root) {
// TODO (bvaughn): If we decide to keep the wrapper component,
// We could create a wrapper for containerTag as well to reduce special casing.
root = ReactNativeFiberRenderer.createContainer(containerTag);
roots.set(containerTag, root);
}
ReactNativeFiberRenderer.updateContainer(element, root, null, callback);
return ReactNativeFiberRenderer.getPublicRootInstance(root);
},
unmountComponentAtNode(containerTag: number) {
const root = roots.get(containerTag);
if (root) {
// TODO: Is it safe to reset this now or should I wait since this unmount could be deferred?
ReactNativeFiberRenderer.updateContainer(null, root, null, () => {
roots.delete(containerTag);
});
}
},
unmountComponentAtNodeAndRemoveContainer(containerTag: number) {
ReactNative.unmountComponentAtNode(containerTag);
// Call back into native to remove all of the subviews from this container
UIManager.removeRootView(containerTag);
},
unstable_createPortal(
children: ReactNodeList,
containerTag: number,
key: ?string = null,
) {
return ReactPortal.createPortal(children, containerTag, null, key);
},
unstable_batchedUpdates: ReactGenericBatching.batchedUpdates,
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
// Used as a mixin in many createClass-based components
NativeMethodsMixin: require('NativeMethodsMixin'),
// Used by react-native-github/Libraries/ components
ReactGlobalSharedState: require('ReactGlobalSharedState'), // Systrace
ReactNativeComponentTree: require('ReactNativeComponentTree'), // InspectorUtils, ScrollResponder
ReactNativePropRegistry: require('ReactNativePropRegistry'), // flattenStyle, Stylesheet
TouchHistoryMath: require('TouchHistoryMath'), // PanResponder
createReactNativeComponentClass: require('createReactNativeComponentClass'), // eg Text
takeSnapshot: require('takeSnapshot'), // react-native-implementation
},
};
if (__DEV__) {
// $FlowFixMe
Object.assign(
ReactNative.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
{
ReactDebugTool: require('ReactDebugTool'), // RCTRenderingPerf, Systrace
ReactPerf: require('ReactPerf'), // ReactPerfStallHandler, RCTRenderingPerf
},
);
}
if (typeof injectInternals === 'function') {
injectInternals({
findFiberByHostInstance: ReactNativeComponentTree.getClosestInstanceFromNode,
findHostInstanceByFiber: ReactNativeFiberRenderer.findHostInstance,
getInspectorDataForViewTag: ReactNativeFiberInspector.getInspectorDataForViewTag,
// This is an enum because we may add more (e.g. profiler build)
bundleType: __DEV__ ? 1 : 0,
version: ReactVersion,
});
}
module.exports = ReactNative;