mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
769136ca3c
Summary:
This diff fixes the render of Text and TextInlineViews when using Fabric + StaticViewConfigs enabled
Similar to Bridgeless mode, we want TextNativeComponent to render "createReactNativeComponentClass('RCTVirtualText..." instead of NativeText.
https://www.internalfb.com/intern/diffusion/FBS/browsefile/master/xplat/js/react-native-github/Libraries/Text/TextNativeComponent.js?commit=f044696a1a273dec1fac227898f5603682d4b19d&lines=59
UIManager.hasViewManagerConfig returns false for all components when using StaticViewConfigs enabled.
I'm changing this method to return true when the component is supported by static view configs:
https://www.internalfb.com/intern/diffusion/FBS/browsefile/master/xplat/js/RKJSModules/EntryPoints/Fb4aBundle.js?commit=4661488cc6aab5078dc6b2afcbb0624e887346d5&lines=81-94
This is correct because hasViewManagerConfig is a new method that's used ONLY in two callsites:
https://www.internalfb.com/intern/diffusion/FBS/browsefile/master/xplat/js/react-native-github/Libraries/Text/TextNativeComponent.js?lines=59
https://www.internalfb.com/intern/diffusion/FBS/browsefile/master/xplat/js/react-native-github/Libraries/Utilities/deprecatedPropType.js?lines=24
Although, this can fail if "hasViewManagerConfig" is started to be used as "feature detection" (see next diffs of the stack)
I'm open to other suggestions (please comment in the diff
My current plan is:
- Land this diff (or similar) to unblock static view configs experiment next week
- Include all codeGenNativeComponents into the list of static view configs
- Migrate callsites of getViewManagerConfig() -> hasNativeConfig() (only for components that have static view configs)
- Think/Discuss/Plan long term plan about feature detection
changelog: [internal] internal
Reviewed By: yungsters
Differential Revision: D26427140
fbshipit-source-id: ce8bf00d6c9793ad17bdc65eb8476aaab63db066
137 lines
4.1 KiB
JavaScript
137 lines
4.1 KiB
JavaScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow strict-local
|
|
* @format
|
|
*/
|
|
|
|
import {createViewConfig} from './ViewConfig';
|
|
import UIManager from '../ReactNative/UIManager';
|
|
import type {
|
|
HostComponent,
|
|
PartialViewConfig,
|
|
} from '../Renderer/shims/ReactNativeTypes';
|
|
import ReactNativeViewConfigRegistry from '../Renderer/shims/ReactNativeViewConfigRegistry';
|
|
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,
|
|
},
|
|
): void {
|
|
invariant(
|
|
getRuntimeConfig == null,
|
|
'NativeComponentRegistry.setRuntimeConfigProvider() called more than once.',
|
|
);
|
|
getRuntimeConfig = runtimeConfigProvider;
|
|
}
|
|
|
|
/**
|
|
* Gets a `NativeComponent` that can be rendered by React Native.
|
|
*
|
|
* The supplied `viewConfigProvider` may or may not be invoked and utilized,
|
|
* depending on how `setRuntimeConfigProvider` is configured.
|
|
*/
|
|
export function get<Config>(
|
|
name: string,
|
|
viewConfigProvider: () => PartialViewConfig,
|
|
): HostComponent<Config> {
|
|
ReactNativeViewConfigRegistry.register(name, () => {
|
|
const {native, verify} = getRuntimeConfig?.(name) ?? {
|
|
native: true,
|
|
verify: false,
|
|
};
|
|
|
|
const viewConfig = native
|
|
? getNativeComponentAttributes(name)
|
|
: createViewConfig(viewConfigProvider());
|
|
|
|
if (verify) {
|
|
if (native) {
|
|
verifyComponentAttributeEquivalence(
|
|
viewConfig,
|
|
createViewConfig(viewConfigProvider()),
|
|
);
|
|
} else {
|
|
verifyComponentAttributeEquivalence(
|
|
getNativeComponentAttributes(name),
|
|
viewConfig,
|
|
);
|
|
}
|
|
}
|
|
|
|
return viewConfig;
|
|
});
|
|
|
|
// $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;
|
|
}
|
|
|
|
/**
|
|
* Unstable API. Do not use!
|
|
*
|
|
* This method returns if there is a StaticViewConfig registered for the
|
|
* component name received as a parameter.
|
|
*/
|
|
export function unstable_hasStaticViewConfig(name: string): boolean {
|
|
const {native} = getRuntimeConfig?.(name) ?? {
|
|
native: true,
|
|
};
|
|
return !native;
|
|
}
|