Skip to content

Commit

Permalink
RN: Add NativeComponentRegistry.getWithFallback_DEPRECATED
Browse files Browse the repository at this point in the history
Summary:
Creates `NativeComponentRegistry.getWithFallback_DEPRECATED`. This is deprecated from inception because it exists only to support a pattern that should not be necessary.

For any given `NativeX` component, the JavaScript module that calls `NativeComponentRegistry.get('NativeX', …)` should only exist in the JavaScript bundle if the native binary actually supports that native component.

But in today's transitional state of the world, there are JavaScript modules that use `UIManager.getViewManagerConfig('NativeX')` as a means of feature detection.

The purpose of `NativeComponentRegistry.getWithFallback_DEPRECATED` is to bridge this transitional gap. Component should migrate toward initializing the `NativeComponentRegistry` with a runtime configuration provider that enumerates all supported native components. If the native component is not supported, it should return null.

Changelog:
[Internal]

Reviewed By: fkgozali

Differential Revision: D25109988

fbshipit-source-id: 76f7077904594ca63495d8338905c43712ea02e0
  • Loading branch information
yungsters authored and facebook-github-bot committed Nov 21, 2020
1 parent a865bd8 commit f638aff
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
49 changes: 48 additions & 1 deletion Libraries/NativeComponent/NativeComponentRegistry.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
'use strict';

import {createViewConfig} from './ViewConfig';
import UIManager from '../ReactNative/UIManager';
import type {
HostComponent,
PartialViewConfig,
Expand All @@ -19,15 +20,24 @@ import ReactNativeViewConfigRegistry from '../Renderer/shims/ReactNativeViewConf
import getNativeComponentAttributes from '../ReactNative/getNativeComponentAttributes';
import verifyComponentAttributeEquivalence from '../Utilities/verifyComponentAttributeEquivalence';
import invariant from 'invariant';
import * as React from 'react';

let getRuntimeConfig;

/**
* Configures a function that is called to determine whether a given component
* should be registered using reflection of the native component at runtime.
*
* The provider should return null if the native component is unavailable in
* the current environment.
*/
export function setRuntimeConfigProvider(
runtimeConfigProvider: (name: string) => {native: boolean, verify: boolean},
runtimeConfigProvider: (
name: string,
) => ?{
native: boolean,
verify: boolean,
},
): void {
invariant(
getRuntimeConfig == null,
Expand Down Expand Up @@ -76,3 +86,40 @@ export function get<Config>(
// $FlowFixMe[incompatible-return] `NativeComponent` is actually string!
return name;
}

/**
* Same as `NativeComponentRegistry.get(...)`, except this will check either
* the `setRuntimeConfigProvider` configuration or use native reflection (slow)
* to determine whether this native component is available.
*
* If the native component is not available, a stub component is returned. Note
* that the return value of this is not `HostComponent` because the returned
* component instance is not guaranteed to have native methods.
*/
export function getWithFallback_DEPRECATED<Config>(
name: string,
viewConfigProvider: () => PartialViewConfig,
): React.AbstractComponent<Config> {
if (getRuntimeConfig == null) {
// If `setRuntimeConfigProvider` is not configured, use native reflection.
if (hasNativeViewConfig(name)) {
return get<Config>(name, viewConfigProvider);
}
} else {
// If there is no runtime config, then the native component is unavailable.
if (getRuntimeConfig(name) != null) {
return get<Config>(name, viewConfigProvider);
}
}

const FallbackNativeComponent = function(props: Config): React.Node {
return null;
};
FallbackNativeComponent.displayName = `Fallback(${name})`;
return FallbackNativeComponent;
}

function hasNativeViewConfig(name: string): boolean {
invariant(getRuntimeConfig == null, 'Unexpected invocation!');
return UIManager.getViewManagerConfig(name) != null;
}
3 changes: 3 additions & 0 deletions jest/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,9 @@ jest
get: jest.fn((name, viewConfigProvider) => {
return jest.requireActual('./mockNativeComponent')(name);
}),
getWithFallback_DEPRECATED: jest.fn((name, viewConfigProvider) => {
return jest.requireActual('./mockNativeComponent')(name);
}),
setRuntimeConfigProvider: jest.fn(),
};
})
Expand Down

0 comments on commit f638aff

Please sign in to comment.