From b96dd668d36dba2649f17b90828e98c3078d5094 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Sun, 1 Apr 2018 10:26:17 -0700 Subject: [PATCH] [add] AppRegistry provider methods Adds support for the following methods in React Native: - setComponentProviderInstrumentationHook - setWrapperComponentProvider --- .../src/exports/AppRegistry/AppContainer.js | 25 +++++--- .../renderApplication-test.js.snap | 1 + .../src/exports/AppRegistry/index.js | 36 +++++++++-- .../exports/AppRegistry/renderApplication.js | 13 ++-- .../2-apis/AppRegistry/AppRegistryScreen.js | 62 +++++++++++-------- 5 files changed, 95 insertions(+), 42 deletions(-) diff --git a/packages/react-native-web/src/exports/AppRegistry/AppContainer.js b/packages/react-native-web/src/exports/AppRegistry/AppContainer.js index 1db8ff0ef..9ad9ee641 100644 --- a/packages/react-native-web/src/exports/AppRegistry/AppContainer.js +++ b/packages/react-native-web/src/exports/AppRegistry/AppContainer.js @@ -11,13 +11,14 @@ import StyleSheet from '../StyleSheet'; import View from '../View'; import { any, node } from 'prop-types'; -import React, { Component } from 'react'; +import React, { Component, type ComponentType } from 'react'; type Context = { rootTag: any }; type Props = { + WrapperComponent?: ?ComponentType<*>, // $FlowFixMe children?: React.Children, rootTag: any @@ -35,6 +36,7 @@ export default class AppContainer extends Component { }; static propTypes = { + WrapperComponent: any, children: node, rootTag: any.isRequired }; @@ -46,14 +48,23 @@ export default class AppContainer extends Component { } render() { + const { children, WrapperComponent } = this.props; + let innerView = ( + + ); + + if (WrapperComponent) { + innerView = {innerView}; + } + return ( - + {innerView} ); } diff --git a/packages/react-native-web/src/exports/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap b/packages/react-native-web/src/exports/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap index 9e342c2dc..af214b72e 100644 --- a/packages/react-native-web/src/exports/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap +++ b/packages/react-native-web/src/exports/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap @@ -11,6 +11,7 @@ exports[`Additional CSS for styled app 1`] = ` exports[`AppRegistry/renderApplication getApplication returns "element" and "getStyleElement" 1`] = ` diff --git a/packages/react-native-web/src/exports/AppRegistry/index.js b/packages/react-native-web/src/exports/AppRegistry/index.js index 7bc7da52a..a21655994 100644 --- a/packages/react-native-web/src/exports/AppRegistry/index.js +++ b/packages/react-native-web/src/exports/AppRegistry/index.js @@ -18,6 +18,15 @@ const emptyObject = {}; const runnables = {}; export type ComponentProvider = () => ComponentType; +export type ComponentProviderInstrumentationHook = ( + component: ComponentProvider +) => ComponentType; +export type WrapperComponentProvider = any => ComponentType<*>; + +let componentProviderInstrumentationHook: ComponentProviderInstrumentationHook = ( + component: ComponentProvider +) => component(); +let wrapperComponentProvider: ?WrapperComponentProvider; export type AppConfig = { appKey: string, @@ -44,12 +53,21 @@ export default class AppRegistry { return runnables[appKey].getApplication(appParameters); } - static registerComponent(appKey: string, getComponentFunc: ComponentProvider): string { + static registerComponent(appKey: string, componentProvider: ComponentProvider): string { runnables[appKey] = { - getApplication: ({ initialProps } = emptyObject) => - getApplication(getComponentFunc(), initialProps), - run: ({ initialProps = emptyObject, rootTag }) => - renderApplication(getComponentFunc(), initialProps, rootTag) + getApplication: appParameters => + getApplication( + componentProviderInstrumentationHook(componentProvider), + appParameters.initialProps || emptyObject, + wrapperComponentProvider && wrapperComponentProvider(appParameters) + ), + run: appParameters => + renderApplication( + componentProviderInstrumentationHook(componentProvider), + appParameters.initialProps || emptyObject, + appParameters.rootTag, + wrapperComponentProvider && wrapperComponentProvider(appParameters) + ) }; return appKey; } @@ -91,6 +109,14 @@ export default class AppRegistry { runnables[appKey].run(appParameters); } + static setComponentProviderInstrumentationHook(hook: ComponentProviderInstrumentationHook) { + componentProviderInstrumentationHook = hook; + } + + static setWrapperComponentProvider(provider: WrapperComponentProvider) { + wrapperComponentProvider = provider; + } + static unmountApplicationComponentAtRootTag(rootTag: Object) { unmountComponentAtNode(rootTag); } diff --git a/packages/react-native-web/src/exports/AppRegistry/renderApplication.js b/packages/react-native-web/src/exports/AppRegistry/renderApplication.js index 9673d86ec..5ff459677 100644 --- a/packages/react-native-web/src/exports/AppRegistry/renderApplication.js +++ b/packages/react-native-web/src/exports/AppRegistry/renderApplication.js @@ -20,21 +20,26 @@ const renderFn = process.env.NODE_ENV !== 'production' ? render : hydrate; export default function renderApplication( RootComponent: ComponentType, initialProps: Props, - rootTag: any + rootTag: any, + WrapperComponent?: ?ComponentType<*> ) { invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag); renderFn( - + , rootTag ); } -export function getApplication(RootComponent: ComponentType, initialProps: Object): Object { +export function getApplication( + RootComponent: ComponentType, + initialProps: Object, + WrapperComponent?: ?ComponentType<*> +): Object { const element = ( - + ); diff --git a/website/storybook/2-apis/AppRegistry/AppRegistryScreen.js b/website/storybook/2-apis/AppRegistry/AppRegistryScreen.js index aaa6b9045..88d1243ca 100644 --- a/website/storybook/2-apis/AppRegistry/AppRegistryScreen.js +++ b/website/storybook/2-apis/AppRegistry/AppRegistryScreen.js @@ -19,24 +19,22 @@ const AppRegistryScreen = () => ( AppRegistry is the control point for registering, running, prerendering, and unmounting all apps. App root components should register themselves with{' '} AppRegistry.registerComponent. Apps can be run by invoking{' '} - AppRegistry.runApplication + AppRegistry.runApplication.
- Register multiple applications. AppConfig type is: - , - {`{ - appKey: string; - component: ComponentProvider; - run?: function -}`} - ]} - name="static registerConfig" - typeInfo="(config: Array) => avoid" + description="Returns all registered app keys" + name="static getAppKeys" + typeInfo="() => Array" + /> + + ( typeInfo="(appKey: string, getComponentFunc: ComponentProvider) => void" /> + + Register multiple applications. AppConfig type is: + , + {`{ + appKey: string; + component: ComponentProvider; + run?: function +}`} + ]} + name="static registerConfig" + typeInfo="(config: Array) => avoid" + /> + @@ -63,12 +76,6 @@ const AppRegistryScreen = () => ( typeInfo="(appKey: string, run: Function) => void" /> - - @@ -87,6 +94,16 @@ const AppRegistryScreen = () => ( typeInfo="(appKey: string, appParameters?: object) => void" /> + + + + @@ -98,13 +115,6 @@ const AppRegistryScreen = () => ( name="static unmountApplicationComponentAtRootTag" typeInfo="(rootTag: HTMLElement) => void" /> - -
);