Skip to content

Commit

Permalink
Support findNodeHandle in Fabric (#12573)
Browse files Browse the repository at this point in the history
This doesn't actually need to share any state because it goes through
the instance to the fiber structure. Since Fabric is on the same version
as RN, calling it on either renderer works.
  • Loading branch information
sebmarkbage authored Apr 8, 2018
1 parent 6bf2797 commit bc753a7
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 27 deletions.
4 changes: 2 additions & 2 deletions packages/react-native-renderer/src/ReactFabric.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ import ReactFabricRenderer from './ReactFabricRenderer';
import ReactNativePropRegistry from './ReactNativePropRegistry';
import {getInspectorDataForViewTag} from './ReactNativeFiberInspector';
import createReactNativeComponentClass from './createReactNativeComponentClass';
import {injectFindHostInstanceFabric} from './findNodeHandle';
import {injectFindHostInstance} from './findNodeHandle';
import findNumericNodeHandle from './findNumericNodeHandle';
import takeSnapshot from './takeSnapshot';

injectFindHostInstanceFabric(ReactFabricRenderer.findHostInstance);
injectFindHostInstance(ReactFabricRenderer.findHostInstance);

ReactGenericBatching.injection.injectRenderer(ReactFabricRenderer);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment node
*/

'use strict';

let React;
let ReactFabric;
let ReactNative;
let createReactNativeComponentClass;

describe('ReactFabric', () => {
beforeEach(() => {
jest.resetModules();
ReactNative = require('react-native-renderer');
jest.resetModules();
jest.mock('shared/ReactFeatureFlags', () =>
require('shared/forks/ReactFeatureFlags.native-fabric'),
);

React = require('react');
ReactFabric = require('react-native-renderer/fabric');
createReactNativeComponentClass = require('../createReactNativeComponentClass')
.default;
});

it('find Fabric nodes with the RN renderer', () => {
const View = createReactNativeComponentClass('View', () => ({
validAttributes: {title: true},
uiViewClassName: 'View',
}));

let ref = React.createRef();

class Component extends React.Component {
render() {
return <View title="foo" />;
}
}

ReactFabric.render(<Component ref={ref} />, 11);

let handle = ReactNative.findNodeHandle(ref.current);
expect(handle).toBe(2);
});
});
26 changes: 1 addition & 25 deletions packages/react-native-renderer/src/findNodeHandle.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,14 @@ import getComponentName from 'shared/getComponentName';
import invariant from 'fbjs/lib/invariant';
import warning from 'fbjs/lib/warning';

// TODO: Share this module between Fabric and React Native renderers
// so that both can be used in the same tree.

let findHostInstance = function(fiber: Fiber): any {
return null;
};

let findHostInstanceFabric = function(fiber: Fiber): any {
return null;
};

export function injectFindHostInstance(impl: (fiber: Fiber) => any) {
findHostInstance = impl;
}

export function injectFindHostInstanceFabric(impl: (fiber: Fiber) => any) {
findHostInstanceFabric = impl;
}

/**
* ReactNative vs ReactWeb
* -----------------------
Expand Down Expand Up @@ -98,24 +87,11 @@ function findNodeHandle(componentOrHandle: any): any {
// ReactInstanceMap.get here will always succeed for mounted components
const internalInstance: Fiber = ReactInstanceMap.get(component);
if (internalInstance) {
return (
findHostInstance(internalInstance) ||
findHostInstanceFabric(internalInstance)
);
return findHostInstance(internalInstance);
} else {
if (component) {
return component;
} else {
invariant(
// Native
(typeof component === 'object' && '_nativeTag' in component) ||
// Composite
(component.render != null && typeof component.render === 'function'),
'findNodeHandle(...): Argument is not a component ' +
'(type: %s, keys: %s)',
typeof component,
Object.keys(component),
);
invariant(
false,
'findNodeHandle(...): Unable to find node handle for unmounted ' +
Expand Down
3 changes: 3 additions & 0 deletions packages/react-native-renderer/src/findNumericNodeHandle.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ export default function findNumericNodeHandleFiber(
if (instance == null || typeof instance === 'number') {
return instance;
}
if (instance.canonical) {
return instance.canonical._nativeTag;
}
return instance._nativeTag;
}

0 comments on commit bc753a7

Please sign in to comment.