mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-06-05 03:09:23 +00:00
[add] AppRegistry provider methods
Adds support for the following methods in React Native: - setComponentProviderInstrumentationHook - setWrapperComponentProvider
This commit is contained in:
@@ -11,13 +11,14 @@
|
|||||||
import StyleSheet from '../StyleSheet';
|
import StyleSheet from '../StyleSheet';
|
||||||
import View from '../View';
|
import View from '../View';
|
||||||
import { any, node } from 'prop-types';
|
import { any, node } from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component, type ComponentType } from 'react';
|
||||||
|
|
||||||
type Context = {
|
type Context = {
|
||||||
rootTag: any
|
rootTag: any
|
||||||
};
|
};
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
WrapperComponent?: ?ComponentType<*>,
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
children?: React.Children,
|
children?: React.Children,
|
||||||
rootTag: any
|
rootTag: any
|
||||||
@@ -35,6 +36,7 @@ export default class AppContainer extends Component<Props, State> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
WrapperComponent: any,
|
||||||
children: node,
|
children: node,
|
||||||
rootTag: any.isRequired
|
rootTag: any.isRequired
|
||||||
};
|
};
|
||||||
@@ -46,14 +48,23 @@ export default class AppContainer extends Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { children, WrapperComponent } = this.props;
|
||||||
|
let innerView = (
|
||||||
|
<View
|
||||||
|
children={children}
|
||||||
|
key={this.state.mainKey}
|
||||||
|
pointerEvents="box-none"
|
||||||
|
style={styles.appContainer}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (WrapperComponent) {
|
||||||
|
innerView = <WrapperComponent>{innerView}</WrapperComponent>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View pointerEvents="box-none" style={styles.appContainer}>
|
<View pointerEvents="box-none" style={styles.appContainer}>
|
||||||
<View
|
{innerView}
|
||||||
children={this.props.children}
|
|
||||||
key={this.state.mainKey}
|
|
||||||
pointerEvents="box-none"
|
|
||||||
style={styles.appContainer}
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -11,6 +11,7 @@ exports[`Additional CSS for styled app 1`] = `
|
|||||||
|
|
||||||
exports[`AppRegistry/renderApplication getApplication returns "element" and "getStyleElement" 1`] = `
|
exports[`AppRegistry/renderApplication getApplication returns "element" and "getStyleElement" 1`] = `
|
||||||
<AppContainer
|
<AppContainer
|
||||||
|
WrapperComponent={undefined}
|
||||||
rootTag={Object {}}
|
rootTag={Object {}}
|
||||||
>
|
>
|
||||||
<RootComponent />
|
<RootComponent />
|
||||||
|
|||||||
+31
-5
@@ -18,6 +18,15 @@ const emptyObject = {};
|
|||||||
const runnables = {};
|
const runnables = {};
|
||||||
|
|
||||||
export type ComponentProvider = () => ComponentType<any>;
|
export type ComponentProvider = () => ComponentType<any>;
|
||||||
|
export type ComponentProviderInstrumentationHook = (
|
||||||
|
component: ComponentProvider
|
||||||
|
) => ComponentType<any>;
|
||||||
|
export type WrapperComponentProvider = any => ComponentType<*>;
|
||||||
|
|
||||||
|
let componentProviderInstrumentationHook: ComponentProviderInstrumentationHook = (
|
||||||
|
component: ComponentProvider
|
||||||
|
) => component();
|
||||||
|
let wrapperComponentProvider: ?WrapperComponentProvider;
|
||||||
|
|
||||||
export type AppConfig = {
|
export type AppConfig = {
|
||||||
appKey: string,
|
appKey: string,
|
||||||
@@ -44,12 +53,21 @@ export default class AppRegistry {
|
|||||||
return runnables[appKey].getApplication(appParameters);
|
return runnables[appKey].getApplication(appParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
static registerComponent(appKey: string, getComponentFunc: ComponentProvider): string {
|
static registerComponent(appKey: string, componentProvider: ComponentProvider): string {
|
||||||
runnables[appKey] = {
|
runnables[appKey] = {
|
||||||
getApplication: ({ initialProps } = emptyObject) =>
|
getApplication: appParameters =>
|
||||||
getApplication(getComponentFunc(), initialProps),
|
getApplication(
|
||||||
run: ({ initialProps = emptyObject, rootTag }) =>
|
componentProviderInstrumentationHook(componentProvider),
|
||||||
renderApplication(getComponentFunc(), initialProps, rootTag)
|
appParameters.initialProps || emptyObject,
|
||||||
|
wrapperComponentProvider && wrapperComponentProvider(appParameters)
|
||||||
|
),
|
||||||
|
run: appParameters =>
|
||||||
|
renderApplication(
|
||||||
|
componentProviderInstrumentationHook(componentProvider),
|
||||||
|
appParameters.initialProps || emptyObject,
|
||||||
|
appParameters.rootTag,
|
||||||
|
wrapperComponentProvider && wrapperComponentProvider(appParameters)
|
||||||
|
)
|
||||||
};
|
};
|
||||||
return appKey;
|
return appKey;
|
||||||
}
|
}
|
||||||
@@ -91,6 +109,14 @@ export default class AppRegistry {
|
|||||||
runnables[appKey].run(appParameters);
|
runnables[appKey].run(appParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static setComponentProviderInstrumentationHook(hook: ComponentProviderInstrumentationHook) {
|
||||||
|
componentProviderInstrumentationHook = hook;
|
||||||
|
}
|
||||||
|
|
||||||
|
static setWrapperComponentProvider(provider: WrapperComponentProvider) {
|
||||||
|
wrapperComponentProvider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
static unmountApplicationComponentAtRootTag(rootTag: Object) {
|
static unmountApplicationComponentAtRootTag(rootTag: Object) {
|
||||||
unmountComponentAtNode(rootTag);
|
unmountComponentAtNode(rootTag);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,21 +20,26 @@ const renderFn = process.env.NODE_ENV !== 'production' ? render : hydrate;
|
|||||||
export default function renderApplication<Props: Object>(
|
export default function renderApplication<Props: Object>(
|
||||||
RootComponent: ComponentType<Props>,
|
RootComponent: ComponentType<Props>,
|
||||||
initialProps: Props,
|
initialProps: Props,
|
||||||
rootTag: any
|
rootTag: any,
|
||||||
|
WrapperComponent?: ?ComponentType<*>
|
||||||
) {
|
) {
|
||||||
invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag);
|
invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag);
|
||||||
|
|
||||||
renderFn(
|
renderFn(
|
||||||
<AppContainer rootTag={rootTag}>
|
<AppContainer WrapperComponent={WrapperComponent} rootTag={rootTag}>
|
||||||
<RootComponent {...initialProps} />
|
<RootComponent {...initialProps} />
|
||||||
</AppContainer>,
|
</AppContainer>,
|
||||||
rootTag
|
rootTag
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getApplication(RootComponent: ComponentType<Object>, initialProps: Object): Object {
|
export function getApplication(
|
||||||
|
RootComponent: ComponentType<Object>,
|
||||||
|
initialProps: Object,
|
||||||
|
WrapperComponent?: ?ComponentType<*>
|
||||||
|
): Object {
|
||||||
const element = (
|
const element = (
|
||||||
<AppContainer rootTag={{}}>
|
<AppContainer WrapperComponent={WrapperComponent} rootTag={{}}>
|
||||||
<RootComponent {...initialProps} />
|
<RootComponent {...initialProps} />
|
||||||
</AppContainer>
|
</AppContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -19,11 +19,37 @@ const AppRegistryScreen = () => (
|
|||||||
AppRegistry is the control point for registering, running, prerendering, and unmounting all
|
AppRegistry is the control point for registering, running, prerendering, and unmounting all
|
||||||
apps. App root components should register themselves with{' '}
|
apps. App root components should register themselves with{' '}
|
||||||
<Code>AppRegistry.registerComponent</Code>. Apps can be run by invoking{' '}
|
<Code>AppRegistry.registerComponent</Code>. Apps can be run by invoking{' '}
|
||||||
<Code>AppRegistry.runApplication</Code>
|
<Code>AppRegistry.runApplication</Code>.
|
||||||
</AppText>
|
</AppText>
|
||||||
</Description>
|
</Description>
|
||||||
|
|
||||||
<Section title="Methods">
|
<Section title="Methods">
|
||||||
|
<DocItem
|
||||||
|
description="Returns all registered app keys"
|
||||||
|
name="static getAppKeys"
|
||||||
|
typeInfo="() => Array<string>"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DocItem
|
||||||
|
description="Use this for server-side rendering to HTML. Returns a object of the given application's element, and a function to get styles once the element is rendered."
|
||||||
|
label="web"
|
||||||
|
name="static getApplication"
|
||||||
|
typeInfo="(appKey: string, appParameters: ?object) => { element: ReactElement; getStyleElement: () => ReactElement }"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DocItem
|
||||||
|
description={
|
||||||
|
<AppText>
|
||||||
|
Register a component provider under the given <Code>appKey</Code>.
|
||||||
|
</AppText>
|
||||||
|
}
|
||||||
|
example={{
|
||||||
|
code: 'AppRegistry.registerComponent("MyApp", () => AppComponent)'
|
||||||
|
}}
|
||||||
|
name="static registerComponent"
|
||||||
|
typeInfo="(appKey: string, getComponentFunc: ComponentProvider) => void"
|
||||||
|
/>
|
||||||
|
|
||||||
<DocItem
|
<DocItem
|
||||||
description={[
|
description={[
|
||||||
<AppText>
|
<AppText>
|
||||||
@@ -39,19 +65,6 @@ const AppRegistryScreen = () => (
|
|||||||
typeInfo="(config: Array<AppConfig>) => avoid"
|
typeInfo="(config: Array<AppConfig>) => avoid"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<DocItem
|
|
||||||
description={
|
|
||||||
<AppText>
|
|
||||||
Register a component provider under the given <Code>appKey</Code>.
|
|
||||||
</AppText>
|
|
||||||
}
|
|
||||||
example={{
|
|
||||||
code: 'AppRegistry.registerComponent("MyApp", () => AppComponent)'
|
|
||||||
}}
|
|
||||||
name="static registerComponent"
|
|
||||||
typeInfo="(appKey: string, getComponentFunc: ComponentProvider) => void"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<DocItem
|
<DocItem
|
||||||
description={
|
description={
|
||||||
<AppText>
|
<AppText>
|
||||||
@@ -63,12 +76,6 @@ const AppRegistryScreen = () => (
|
|||||||
typeInfo="(appKey: string, run: Function) => void"
|
typeInfo="(appKey: string, run: Function) => void"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<DocItem
|
|
||||||
description="Returns all registered app keys"
|
|
||||||
name="static getAppKeys"
|
|
||||||
typeInfo="() => Array<string>"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<DocItem
|
<DocItem
|
||||||
description={
|
description={
|
||||||
<AppText>
|
<AppText>
|
||||||
@@ -87,6 +94,16 @@ const AppRegistryScreen = () => (
|
|||||||
typeInfo="(appKey: string, appParameters?: object) => void"
|
typeInfo="(appKey: string, appParameters?: object) => void"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<DocItem
|
||||||
|
name="static setComponentProviderInstrumentationHook"
|
||||||
|
typeInfo="(componentProvider: func) => Component"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DocItem
|
||||||
|
name="static setWrapperComponentProvider"
|
||||||
|
typeInfo="(appParameters: object) => Component"
|
||||||
|
/>
|
||||||
|
|
||||||
<DocItem
|
<DocItem
|
||||||
description={
|
description={
|
||||||
<AppText>
|
<AppText>
|
||||||
@@ -98,13 +115,6 @@ const AppRegistryScreen = () => (
|
|||||||
name="static unmountApplicationComponentAtRootTag"
|
name="static unmountApplicationComponentAtRootTag"
|
||||||
typeInfo="(rootTag: HTMLElement) => void"
|
typeInfo="(rootTag: HTMLElement) => void"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<DocItem
|
|
||||||
description="Use this for server-side rendering to HTML. Returns a object of the given application's element, and a function to get styles once the element is rendered."
|
|
||||||
label="web"
|
|
||||||
name="static getApplication"
|
|
||||||
typeInfo="(appKey: string, appParameters: ?object) => { element: ReactElement; getStyleElement: () => ReactElement }"
|
|
||||||
/>
|
|
||||||
</Section>
|
</Section>
|
||||||
</UIExplorer>
|
</UIExplorer>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user