Skip to content

Commit

Permalink
Migrating View to be a Flow Typed ES6 class
Browse files Browse the repository at this point in the history
Summary:
The flow type for View using createReactClass was essentially `any`, allowing any Prop to be passed in, only pseudo enforced at run time via propTypes.

This diff converts View away from createReactClass and instead uses ReactNative.NativeComponent. This was previously typed as any as well which didn't buy us much. This change converts View to be an ES6 React class component to ensure proptypechecking, and exposes the methods copied from NativeMethodsMixin.

Reviewed By: yungsters

Differential Revision: D5933888

fbshipit-source-id: eae63b818203e0e86741f9f154ec9cf3498369e2
  • Loading branch information
TheSavior authored and facebook-github-bot committed Mar 10, 2018
1 parent 1ff1e57 commit 26734a8
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 58 deletions.
42 changes: 13 additions & 29 deletions Libraries/Components/View/View.js
Expand Up @@ -10,15 +10,13 @@
*/
'use strict';

const NativeMethodsMixin = require('NativeMethodsMixin');
const Platform = require('Platform');
const React = require('React');
const ReactNative = require('ReactNative');
const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes');
const ReactNativeViewAttributes = require('ReactNativeViewAttributes');
const ViewPropTypes = require('ViewPropTypes');
const {ViewContextTypes} = require('ViewContext');

const createReactClass = require('create-react-class');
const invariant = require('fbjs/lib/invariant');
const requireNativeComponent = require('requireNativeComponent');

Expand All @@ -28,40 +26,26 @@ import type {ViewChildContext} from 'ViewContext';
export type Props = ViewProps;

/**
* The most fundamental component for building a UI.
* The most fundamental component for building a UI, View is a container that
* supports layout with flexbox, style, some touch handling, and accessibility
* controls.
*
* See http://facebook.github.io/react-native/docs/view.html
* @see http://facebook.github.io/react-native/docs/view.html
*/
const View = createReactClass({
displayName: 'View',
// TODO: We should probably expose the mixins, viewConfig, and statics publicly. For example,
// one of the props is of type AccessibilityComponentType. That is defined as a const[] above,
// but it is not rendered by the docs, since `statics` below is not rendered. So its Possible
// values had to be hardcoded.
mixins: [NativeMethodsMixin],

// `propTypes` should not be accessed directly on View since this wrapper only
// exists for DEV mode. However it's important for them to be declared.
// If the object passed to `createClass` specifies `propTypes`, Flow will
// create a static type from it.
propTypes: ViewPropTypes,
class View extends ReactNative.NativeComponent<Props> {
static propTypes = ViewPropTypes;
static childContextTypes = ViewContextTypes;

/**
* `NativeMethodsMixin` will look for this when invoking `setNativeProps`. We
* make `this` look like an actual native component class.
*/
viewConfig: {
viewConfig = {
uiViewClassName: 'RCTView',
validAttributes: ReactNativeViewAttributes.RCTView,
},

childContextTypes: ViewContextTypes,
};

getChildContext(): ViewChildContext {
return {
isInAParentText: false,
};
},
}

render() {
invariant(
Expand All @@ -74,8 +58,8 @@ const View = createReactClass({
// adding functionality this component that you'd want to be available in both
// dev and prod modes.
return <RCTView {...this.props} />;
},
});
}
}

const RCTView = requireNativeComponent('RCTView', View, {
nativeOnly: {
Expand Down
28 changes: 0 additions & 28 deletions Libraries/Components/View/View.js.flow

This file was deleted.

17 changes: 16 additions & 1 deletion Libraries/Renderer/shims/ReactNativeTypes.js
Expand Up @@ -86,12 +86,27 @@ type SecretInternalsType = {
// And how much information to fill in for the above types.
};

declare class ReactNativeComponent<Props, State = void>
extends React$Component<Props, State> {

blur(): void,
focus(): void,
measure(callback: MeasureOnSuccessCallback): void,
measureInWindow(callback: MeasureInWindowOnSuccessCallback): void,
measureLayout(
relativeToNativeNode: number,
onSuccess: MeasureLayoutOnSuccessCallback,
onFail: () => void,
): void,
setNativeProps(nativeProps: Object): void,
}

/**
* Flat ReactNative renderer bundles are too big for Flow to parse efficiently.
* Provide minimal Flow typing for the high-level RN API and call it a day.
*/
export type ReactNativeType = {
NativeComponent: any,
NativeComponent: typeof ReactNativeComponent,
findNodeHandle(componentOrHandle: any): ?number,
render(
element: React$Element<any>,
Expand Down

0 comments on commit 26734a8

Please sign in to comment.