Files
react/packages/react-native-renderer/src/ReactNativeComponent.js
T
Dan AbramovandGitHub ad205193d3 Use Yarn Workspaces (#11252)
* Enable Yarn workspaces for packages/*

* Move src/isomorphic/* into packages/react/src/*

* Create index.js stubs for all packages in packages/*

This makes the test pass again, but breaks the build because npm/ folders aren't used yet.
I'm not sure if we'll keep this structure--I'll just keep working and fix the build after it settles down.

* Put FB entry point for react-dom into packages/*

* Move src/renderers/testing/* into packages/react-test-renderer/src/*

Note that this is currently broken because Jest ignores node_modules,
and so Yarn linking makes Jest skip React source when transforming.

* Remove src/node_modules

It is now unnecessary. Some tests fail though.

* Add a hacky workaround for Jest/Workspaces issue

Jest sees node_modules and thinks it's third party code.

This is a hacky way to teach Jest to still transform anything in node_modules/react*
if it resolves outside of node_modules (such as to our packages/*) folder.

I'm not very happy with this and we should revisit.

* Add a fake react-native package

* Move src/renderers/art/* into packages/react-art/src/*

* Move src/renderers/noop/* into packages/react-noop-renderer/src/*

* Move src/renderers/dom/* into packages/react-dom/src/*

* Move src/renderers/shared/fiber/* into packages/react-reconciler/src/*

* Move DOM/reconciler tests I previously forgot to move

* Move src/renderers/native-*/* into packages/react-native-*/src/*

* Move shared code into packages/shared

It's not super clear how to organize this properly yet.

* Add back files that somehow got lost

* Fix the build

* Prettier

* Add missing license headers

* Fix an issue that caused mocks to get included into build

* Update other references to src/

* Re-run Prettier

* Fix lint

* Fix weird Flow violation

I didn't change this file but Flow started complaining.
Caleb said this annotation was unnecessarily using $Abstract though so I removed it.

* Update sizes

* Fix stats script

* Fix packaging fixtures

Use file: instead of NODE_PATH since NODE_PATH.
NODE_PATH trick only worked because we had no react/react-dom in root node_modules, but now we do.

file: dependency only works as I expect in Yarn, so I moved the packaging fixtures to use Yarn and committed lockfiles.
Verified that the page shows up.

* Fix art fixture

* Fix reconciler fixture

* Fix SSR fixture

* Rename native packages
2017-10-19 00:22:21 +01:00

177 lines
5.5 KiB
JavaScript

/**
* 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.
*
* @providesModule ReactNativeComponent
* @flow
* @format
*/
'use strict';
const React = require('react');
const ReactNativeAttributePayload = require('ReactNativeAttributePayload');
const TextInputState = require('TextInputState');
const UIManager = require('UIManager');
const findNodeHandle = require('findNodeHandle');
const findNumericNodeHandle = require('findNumericNodeHandle');
const {mountSafeCallback} = require('NativeMethodsMixinUtils');
import type {
MeasureInWindowOnSuccessCallback,
MeasureLayoutOnSuccessCallback,
MeasureOnSuccessCallback,
NativeMethodsMixinType,
ReactNativeBaseComponentViewConfig,
} from 'ReactNativeTypes';
/**
* Superclass that provides methods to access the underlying native component.
* This can be useful when you want to focus a view or measure its dimensions.
*
* Methods implemented by this class are available on most default components
* provided by React Native. However, they are *not* available on composite
* components that are not directly backed by a native view. For more
* information, see [Direct Manipulation](docs/direct-manipulation.html).
*
* @abstract
*/
class ReactNativeComponent<DefaultProps, Props, State>
extends React.Component<Props, State> {
static defaultProps: $Abstract<DefaultProps>;
props: Props;
state: State;
/**
* Removes focus. This is the opposite of `focus()`.
*/
blur(): void {
TextInputState.blurTextInput(findNumericNodeHandle(this));
}
/**
* Requests focus. The exact behavior depends on the platform and view.
*/
focus(): void {
TextInputState.focusTextInput(findNumericNodeHandle(this));
}
/**
* Measures the on-screen location and dimensions. If successful, the callback
* will be called asynchronously with the following arguments:
*
* - x
* - y
* - width
* - height
* - pageX
* - pageY
*
* These values are not available until after natives rendering completes. If
* you need the measurements as soon as possible, consider using the
* [`onLayout` prop](docs/view.html#onlayout) instead.
*/
measure(callback: MeasureOnSuccessCallback): void {
UIManager.measure(
findNumericNodeHandle(this),
mountSafeCallback(this, callback),
);
}
/**
* Measures the on-screen location and dimensions. Even if the React Native
* root view is embedded within another native view, this method will give you
* the absolute coordinates measured from the window. If successful, the
* callback will be called asynchronously with the following arguments:
*
* - x
* - y
* - width
* - height
*
* These values are not available until after natives rendering completes.
*/
measureInWindow(callback: MeasureInWindowOnSuccessCallback): void {
UIManager.measureInWindow(
findNumericNodeHandle(this),
mountSafeCallback(this, callback),
);
}
/**
* Similar to [`measure()`](#measure), but the resulting location will be
* relative to the supplied ancestor's location.
*
* Obtain a native node handle with `ReactNative.findNodeHandle(component)`.
*/
measureLayout(
relativeToNativeNode: number,
onSuccess: MeasureLayoutOnSuccessCallback,
onFail: () => void /* currently unused */,
): void {
UIManager.measureLayout(
findNumericNodeHandle(this),
relativeToNativeNode,
mountSafeCallback(this, onFail),
mountSafeCallback(this, onSuccess),
);
}
/**
* This function sends props straight to native. They will not participate in
* future diff process - this means that if you do not include them in the
* next render, they will remain active (see [Direct
* Manipulation](docs/direct-manipulation.html)).
*/
setNativeProps(nativeProps: Object): void {
// Class components don't have viewConfig -> validateAttributes.
// Nor does it make sense to set native props on a non-native component.
// Instead, find the nearest host component and set props on it.
// Use findNodeHandle() rather than ReactNative.findNodeHandle() because
// We want the instance/wrapper (not the native tag).
let maybeInstance;
// Fiber errors if findNodeHandle is called for an umounted component.
// Tests using ReactTestRenderer will trigger this case indirectly.
// Mimicking stack behavior, we should silently ignore this case.
// TODO Fix ReactTestRenderer so we can remove this try/catch.
try {
maybeInstance = findNodeHandle(this);
} catch (error) {}
// If there is no host component beneath this we should fail silently.
// This is not an error; it could mean a class component rendered null.
if (maybeInstance == null) {
return;
}
const viewConfig: ReactNativeBaseComponentViewConfig =
maybeInstance.viewConfig;
var updatePayload = ReactNativeAttributePayload.create(
nativeProps,
viewConfig.validAttributes,
);
// Avoid the overhead of bridge calls if there's no update.
// This is an expensive no-op for Android, and causes an unnecessary
// view invalidation for certain components (eg RCTTextInput) on iOS.
if (updatePayload != null) {
UIManager.updateView(
maybeInstance._nativeTag,
viewConfig.uiViewClassName,
updatePayload,
);
}
}
}
// eslint-disable-next-line no-unused-expressions
(ReactNativeComponent.prototype: NativeMethodsMixinType);
module.exports = ReactNativeComponent;