Skip to content

Commit

Permalink
Prepare for next React Native sync with new instance format (facebook…
Browse files Browse the repository at this point in the history
…#36438)

Summary:
Pull Request resolved: facebook#36438

This makes the `react-native` repository compatible with the next sync from react after the changes in facebook/react#26321 land.

That PR is changing the format of the Fabric instance and we have a few instances where we assume the internal structure of that instance in the repository.

Changelog: [internal]

Reviewed By: yungsters

Differential Revision: D43980374

fbshipit-source-id: 8b716f2e4a99ac0312bfe6927f364429e94c9574
  • Loading branch information
rubennorte authored and facebook-github-bot committed Mar 13, 2023
1 parent ec09561 commit c51fe74
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 16 deletions.
15 changes: 6 additions & 9 deletions Libraries/Animated/useAnimatedProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

'use strict';

import {isPublicInstance as isFabricPublicInstance} from '../Renderer/public/ReactFabricPublicInstance';
import useRefEffect from '../Utilities/useRefEffect';
import {AnimatedEvent} from './AnimatedEvent';
import NativeAnimatedHelper from './NativeAnimatedHelper';
Expand Down Expand Up @@ -183,7 +184,7 @@ function getEventTarget<TInstance>(instance: TInstance): TInstance {
// $FlowFixMe[unclear-type] - Legacy instance assumptions.
function isFabricInstance(instance: any): boolean {
return (
hasFabricHandle(instance) ||
isFabricPublicInstance(instance) ||
// Some components have a setNativeProps function but aren't a host component
// such as lists like FlatList and SectionList. These should also use
// forceUpdate in Fabric since setNativeProps doesn't exist on the underlying
Expand All @@ -192,13 +193,9 @@ function isFabricInstance(instance: any): boolean {
// If these components end up using forwardRef then these hacks can go away
// as instance would actually be the underlying host component and the above check
// would be sufficient.
hasFabricHandle(instance?.getNativeScrollRef?.()) ||
hasFabricHandle(instance?.getScrollResponder?.()?.getNativeScrollRef?.())
isFabricPublicInstance(instance?.getNativeScrollRef?.()) ||
isFabricPublicInstance(
instance?.getScrollResponder?.()?.getNativeScrollRef?.(),
)
);
}

// $FlowFixMe[unclear-type] - Legacy instance assumptions.
function hasFabricHandle(instance: any): boolean {
// eslint-disable-next-line dot-notation
return instance?.['_internalInstanceHandle']?.stateNode?.canonical != null;
}
6 changes: 2 additions & 4 deletions Libraries/Components/ScrollView/ScrollViewStickyHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import type {LayoutEvent} from '../../Types/CoreEventTypes';

import Animated from '../../Animated/Animated';
import {isPublicInstance as isFabricPublicInstance} from '../../Renderer/public/ReactFabricPublicInstance';
import StyleSheet from '../../StyleSheet/StyleSheet';
import Platform from '../../Utilities/Platform';
import useMergeRefs from '../../Utilities/useMergeRefs';
Expand Down Expand Up @@ -64,10 +65,7 @@ const ScrollViewStickyHeaderWithForwardedRef: React.AbstractComponent<
ref.setNextHeaderY = value => {
setNextHeaderLayoutY(value);
};
// Avoid dot notation because at Meta, private properties are obfuscated.
// $FlowFixMe[prop-missing]
const _internalInstanceHandler = ref['_internalInstanceHandle']; // eslint-disable-line dot-notation
setIsFabric(Boolean(_internalInstanceHandler?.stateNode?.canonical));
setIsFabric(isFabricPublicInstance(ref));
};
const ref: (React.ElementRef<typeof Animated.View> | null) => void =
// $FlowFixMe[incompatible-type] - Ref is mutated by `callbackRef`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ interface Agent {
}

type TraceNode = {
publicInstance?: TraceNode,
// TODO: remove this field when syncing the new version of the renderer from React to React Native.
canonical?: TraceNode,
measure?: (
(
Expand Down Expand Up @@ -100,7 +102,11 @@ export default function TraceUpdateOverlay(): React.Node {

const newFramesToDraw: Array<Promise<Overlay>> = [];
nodesToDraw.forEach(({node, color}) => {
const component = node.canonical ?? node;
// `publicInstance` => Fabric
// TODO: remove this check when syncing the new version of the renderer from React to React Native.
// `canonical` => Legacy Fabric
// `node` => Legacy renderer
const component = node.publicInstance ?? node.canonical ?? node;
if (!component || !component.measure) {
return;
}
Expand Down
8 changes: 6 additions & 2 deletions Libraries/Inspector/DevtoolsOverlay.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,12 @@ export default function DevtoolsOverlay({

function onAgentShowNativeHighlight(node: any) {
clearTimeout(hideTimeoutId);
// Shape of `node` is different in Fabric.
const component = node.canonical ?? node;

// `publicInstance` => Fabric
// TODO: remove this check when syncing the new version of the renderer from React to React Native.
// `canonical` => Legacy Fabric
// `node` => Legacy renderer
const component = node.publicInstance ?? node.canonical ?? node;
if (!component || !component.measure) {
return;
}
Expand Down
30 changes: 30 additions & 0 deletions Libraries/Renderer/public/ReactFabricPublicInstance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict
*/

export function isPublicInstance(maybeInstance: mixed): boolean {
return (
maybeInstance != null &&
// TODO: implement a better check (maybe using instanceof) when the instance is defined in the React Native repository.
(maybeInstance.__nativeTag != null ||
// TODO: remove this check when syncing the new version of the renderer from React to React Native.
isLegacyFabricInstance(maybeInstance))
);
}

function isLegacyFabricInstance(maybeInstance: mixed): boolean {
/* eslint-disable dot-notation */
return (
maybeInstance != null &&
// $FlowExpectedError[incompatible-use]
maybeInstance['_internalInstanceHandle'] != null &&
maybeInstance['_internalInstanceHandle'].stateNode != null &&
maybeInstance['_internalInstanceHandle'].stateNode.canonical != null
);
}

0 comments on commit c51fe74

Please sign in to comment.