Replaced View.propTypes with a static getter that warned about deprecation

Reviewed By: spicyj

Differential Revision: D4766860

fbshipit-source-id: c0ef46df58b6167178e801d9dbe481101c0dc773
This commit is contained in:
Brian Vaughn 2017-03-28 11:17:21 -07:00 committed by Facebook Github Bot
parent 777e80a2b7
commit 1129c6096d
4 changed files with 88 additions and 39 deletions

View File

@ -1854,14 +1854,24 @@ function createAnimatedComponent(Component: any): any {
return this._component;
}
}
// ReactNative `View.propTypes` have been deprecated in favor of
// `ViewPropTypes`. In their place a temporary getter has been added with a
// deprecated warning message. Avoid triggering that warning here by using
// temporary workaround, __propTypesSecretDontUseThesePlease.
// TODO (bvaughn) Revert this particular change any time after April 1
var propTypes =
Component.__propTypesSecretDontUseThesePlease ||
Component.propTypes;
AnimatedComponent.propTypes = {
style: function(props, propName, componentName) {
if (!Component.propTypes) {
if (!propTypes) {
return;
}
for (var key in ViewStylePropTypes) {
if (!Component.propTypes[key] && props[key] !== undefined) {
if (!propTypes[key] && props[key] !== undefined) {
console.warn(
'You are setting the style `{ ' + key + ': ... }` as a prop. You ' +
'should nest it in a style object. ' +

View File

@ -87,6 +87,21 @@ const View = React.createClass({
// 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. This property will be over-written below with
// a warn-on-use getter though.
// TODO (bvaughn) Remove the warn-on-use comment after April 1.
propTypes: ViewPropTypes,
// ReactElementValidator will (temporarily) use this private accessor when
// detected to avoid triggering the warning message.
// TODO (bvaughn) Remove this after April 1 ReactNative RC is tagged.
statics: {
__propTypesSecretDontUseThesePlease: ViewPropTypes
},
/**
* `NativeMethodsMixin` will look for this when invoking `setNativeProps`. We
* make `this` look like an actual native component class.
@ -96,11 +111,6 @@ const View = React.createClass({
validAttributes: ReactNativeViewAttributes.RCTView
},
// TODO (bvaughn) Replace this with a deprecated getter warning. This object
// should be accessible via a separate import. It will not be available in
// production mode in the future and so should not be directly accessed.
propTypes: ViewPropTypes,
contextTypes: {
isInAParentText: React.PropTypes.bool,
},
@ -122,57 +132,64 @@ const View = React.createClass({
// be supported with React fiber. This warning message will go away in the next
// ReactNative release. Use defineProperty() rather than createClass() statics
// because the mixin process auto-triggers the 1-time warning message.
// TODO (bvaughn) Remove these warning messages after the April ReactNative tag.
// TODO (bvaughn) Remove this after April 1 ReactNative RC is tagged.
function mixinStatics (target) {
let warnedAboutAccessibilityTraits = false;
let warnedAboutAccessibilityComponentType = false;
let warnedAboutForceTouchAvailable = false;
let warnedAboutPropTypes = false;
// $FlowFixMe https://github.com/facebook/flow/issues/285
Object.defineProperty(target, 'AccessibilityTraits', {
get: function() {
if (!warnedAboutAccessibilityTraits) {
warnedAboutAccessibilityTraits = true;
warning(
false,
'View.AccessibilityTraits has been deprecated and will be ' +
'removed in a future version of ReactNative. Use ' +
'ViewAccessibility.AccessibilityTraits instead.'
);
}
warning(
warnedAboutAccessibilityTraits,
'View.AccessibilityTraits has been deprecated and will be ' +
'removed in a future version of ReactNative. Use ' +
'ViewAccessibility.AccessibilityTraits instead.'
);
warnedAboutAccessibilityTraits = true;
return AccessibilityTraits;
}
});
// $FlowFixMe https://github.com/facebook/flow/issues/285
Object.defineProperty(target, 'AccessibilityComponentType', {
get: function() {
if (!warnedAboutAccessibilityComponentType) {
warnedAboutAccessibilityComponentType = true;
warning(
false,
'View.AccessibilityComponentType has been deprecated and will be ' +
'removed in a future version of ReactNative. Use ' +
'ViewAccessibility.AccessibilityComponentTypes instead.'
);
}
warning(
warnedAboutAccessibilityComponentType,
'View.AccessibilityComponentType has been deprecated and will be ' +
'removed in a future version of ReactNative. Use ' +
'ViewAccessibility.AccessibilityComponentTypes instead.'
);
warnedAboutAccessibilityComponentType = true;
return AccessibilityComponentTypes;
}
});
// $FlowFixMe https://github.com/facebook/flow/issues/285
Object.defineProperty(target, 'forceTouchAvailable', {
get: function() {
if (!warnedAboutForceTouchAvailable) {
warnedAboutForceTouchAvailable = true;
warning(
false,
'View.forceTouchAvailable has been deprecated and will be removed ' +
'in a future version of ReactNative. Use ' +
'NativeModules.PlatformConstants.forceTouchAvailable instead.'
);
}
warning(
warnedAboutForceTouchAvailable,
'View.forceTouchAvailable has been deprecated and will be removed ' +
'in a future version of ReactNative. Use ' +
'NativeModules.PlatformConstants.forceTouchAvailable instead.'
);
warnedAboutForceTouchAvailable = true;
return forceTouchAvailable;
}
});
// $FlowFixMe https://github.com/facebook/flow/issues/285
Object.defineProperty(target, 'propTypes', {
get: function() {
warning(
warnedAboutPropTypes,
'View.propTypes has been deprecated and will be removed in a future ' +
'version of ReactNative. Use ViewPropTypes instead.'
);
warnedAboutPropTypes = true;
return ViewPropTypes;
}
});
}
const RCTView = requireNativeComponent('RCTView', View, {

View File

@ -55,7 +55,20 @@ function requireNativeComponent(
viewConfig.uiViewClassName = viewName;
viewConfig.validAttributes = {};
viewConfig.propTypes = componentInterface && componentInterface.propTypes;
// ReactNative `View.propTypes` have been deprecated in favor of
// `ViewPropTypes`. In their place a temporary getter has been added with a
// deprecated warning message. Avoid triggering that warning here by using
// temporary workaround, __propTypesSecretDontUseThesePlease.
// TODO (bvaughn) Revert this particular change any time after April 1
if (componentInterface) {
viewConfig.propTypes =
typeof componentInterface.__propTypesSecretDontUseThesePlease === 'object'
? componentInterface.__propTypesSecretDontUseThesePlease
: componentInterface.propTypes;
} else {
viewConfig.propTypes = null;
}
// The ViewConfig doesn't contain any props inherited from the view manager's
// superclass, so we manually merge in the RCTView ones. Other inheritance

View File

@ -32,7 +32,16 @@ function verifyPropTypes(
componentInterface.name ||
'unknown';
if (!componentInterface.propTypes) {
// ReactNative `View.propTypes` have been deprecated in favor of
// `ViewPropTypes`. In their place a temporary getter has been added with a
// deprecated warning message. Avoid triggering that warning here by using
// temporary workaround, __propTypesSecretDontUseThesePlease.
// TODO (bvaughn) Revert this particular change any time after April 1
var propTypes =
(componentInterface : any).__propTypesSecretDontUseThesePlease ||
componentInterface.propTypes;
if (!propTypes) {
throw new Error(
'`' + componentName + '` has no propTypes defined`'
);
@ -40,11 +49,11 @@ function verifyPropTypes(
var nativeProps = viewConfig.NativeProps;
for (var prop in nativeProps) {
if (!componentInterface.propTypes[prop] &&
if (!propTypes[prop] &&
!ReactNativeStyleAttributes[prop] &&
(!nativePropsToIgnore || !nativePropsToIgnore[prop])) {
var message;
if (componentInterface.propTypes.hasOwnProperty(prop)) {
if (propTypes.hasOwnProperty(prop)) {
message = '`' + componentName + '` has incorrectly defined propType for native prop `' +
viewConfig.uiViewClassName + '.' + prop + '` of native type `' + nativeProps[prop];
} else {