Skip to content

Commit

Permalink
Add back deprecated prop-types
Browse files Browse the repository at this point in the history
Summary:
In 2017, React published v15.5 which extracted the built-in `prop types` to a separate package to reflect the fact that not everybody uses them. In 2018, React Native started to remove `PropTypes` from React Native for the same reason. In 0.68 React Native introduced a deprecation warning which notified users that the change was coming, and in 0.69 we removed the PropTypes entirely.

The feedback we've received from the community is that there has not been enough time to migrate libraries off of PropTypes. This has resulted in users needing to patch the React Native package `index.js` file directly to add back the PropTypes, instead of migrating off of them. We can empathize with this fix short term (it unblocks the upgrade) but long term this patch will cause users to miss important changes to `index.js`, and add a maintenance cost for users.

Part of the reason there was not enough time is that we didn't do a good job surfacing libraries that were using PropTypes. This means, when you got a deprecation warning, it wasn't clear where the source of the usage was (either in your code or in a library). So even if you wanted to migrate, it was difficult to know where to actually make the change.

In the next release, we've made it easier to find call sites using deprecated types by [fixing the code frame in errors](react-native-community/cli#1699) reporting in LogBox, and ensuring that [the app doesn't crash without a warning](#34650). This should make it easier to identify exactly where the deprecated usage is, so you can migrate it.

To help users get off of the patch, and allow more time to migrate, we're walking back the removal of PropTypes, and keeping it as a deprecation for a couple more versions. We ask that you either migrate off PropTypes to a type system like TypeScript, or migrate to the `deprecated-react-native-prop-types` package.

Once we feel more confident that the community has migrated and will not need to patch React Native in order to fix this issue, we'll remove the PropTypes again. **If you have any trouble finding the source of the PropType usage, please file an issue so we can help track it down with you.**

Changelog:
[General][Changed] - Add back deprecated PropTypes

Reviewed By: yungsters

Differential Revision: D40725705

fbshipit-source-id: 8ce61be30343827efd6dc89a012eeef0b6676deb
  • Loading branch information
rickhanlonii authored and facebook-github-bot committed Oct 27, 2022
1 parent fa2842d commit b966d29
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 14 deletions.
1 change: 1 addition & 0 deletions BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,7 @@ rn_library(
"//xplat/js:node_modules__abort_19controller",
"//xplat/js:node_modules__anser",
"//xplat/js:node_modules__base64_19js",
"//xplat/js:node_modules__deprecated_19react_19native_19prop_19types",
"//xplat/js:node_modules__event_19target_19shim",
"//xplat/js:node_modules__invariant",
"//xplat/js:node_modules__memoize_19one",
Expand Down
7 changes: 7 additions & 0 deletions Libraries/Components/TextInput/TextInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -1650,6 +1650,13 @@ const ExportedForwardRef: React.AbstractComponent<
);
});

/**
* Switch to `deprecated-react-native-prop-types` for compatibility with future
* releases. This is deprecated and will be removed in the future.
*/
ExportedForwardRef.propTypes =
require('deprecated-react-native-prop-types').TextInputPropTypes;

// $FlowFixMe[prop-missing]
ExportedForwardRef.State = {
currentlyFocusedInput: TextInputState.currentlyFocusedInput,
Expand Down
6 changes: 6 additions & 0 deletions Libraries/Image/Image.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,12 @@ Image.queryCache = queryCache;
* comment and run Flow. */
Image.resolveAssetSource = resolveAssetSource;

/**
* Switch to `deprecated-react-native-prop-types` for compatibility with future
* releases. This is deprecated and will be removed in the future.
*/
Image.propTypes = require('deprecated-react-native-prop-types').ImagePropTypes;

const styles = StyleSheet.create({
base: {
overflow: 'hidden',
Expand Down
6 changes: 6 additions & 0 deletions Libraries/Image/Image.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,12 @@ Image.queryCache = queryCache;
* delete this comment and run Flow. */
Image.resolveAssetSource = resolveAssetSource;

/**
* Switch to `deprecated-react-native-prop-types` for compatibility with future
* releases. This is deprecated and will be removed in the future.
*/
Image.propTypes = require('deprecated-react-native-prop-types').ImagePropTypes;

const styles = StyleSheet.create({
base: {
overflow: 'hidden',
Expand Down
6 changes: 6 additions & 0 deletions Libraries/Text/Text.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,12 @@ const Text: React.AbstractComponent<

Text.displayName = 'Text';

/**
* Switch to `deprecated-react-native-prop-types` for compatibility with future
* releases. This is deprecated and will be removed in the future.
*/
Text.propTypes = require('deprecated-react-native-prop-types').TextPropTypes;

This comment has been minimized.

Copy link
@NickGerleman

NickGerleman Nov 23, 2022

Contributor

@rickhanlonii @yungsters @necolas The prop-types package defining allowed properties is no longer in the repo, but it seems like we may log a console.error() when using newly added properties in one of these components (but not View).

PASS Libraries/Text/__tests__/Text-test.js
  ● Console

    console.error
      Warning: Failed prop type: Invalid props.style key `marginInlineStart` supplied to `Text`.
      Bad object: {
        "display": "flex",
        "flex": 1,
        "backgroundColor": "white",
        "marginInlineStart": 10,
        "userSelect": "none",
        "verticalAlign": "middle"
      }
      Valid keys: [
        "display",
        "width",
        "height",
        "start",
        "end",
        "top",
        "left",
        "right",
        "bottom",
        "minWidth",
        "maxWidth",
        "minHeight",
        "maxHeight",
        "margin",
        "marginVertical",
        "marginHorizontal",
        "marginTop",
        "marginBottom",
        "marginLeft",
        "marginRight",
        "marginStart",
        "marginEnd",
        "padding",
        "paddingVertical",
        "paddingHorizontal",
        "paddingTop",
        "paddingBottom",
        "paddingLeft",
        "paddingRight",
        "paddingStart",
        "paddingEnd",
        "borderWidth",
        "borderTopWidth",
        "borderStartWidth",
        "borderEndWidth",
        "borderRightWidth",
        "borderBottomWidth",
        "borderLeftWidth",
        "position",
        "flexDirection",
        "flexWrap",
        "justifyContent",
        "alignItems",
        "alignSelf",
        "alignContent",
        "overflow",
        "flex",
        "flexGrow",
        "flexShrink",
        "flexBasis",
        "aspectRatio",
        "zIndex",
        "direction",
        "shadowColor",
        "shadowOffset",
        "shadowOpacity",
        "shadowRadius",
        "transform",
        "transformMatrix",
        "decomposedMatrix",
        "scaleX",
        "scaleY",
        "rotation",
        "translateX",
        "translateY",
        "backfaceVisibility",
        "backgroundColor",
        "borderColor",
        "borderTopColor",
        "borderRightColor",
        "borderBottomColor",
        "borderLeftColor",
        "borderStartColor",
        "borderEndColor",
        "borderRadius",
        "borderTopLeftRadius",
        "borderTopRightRadius",
        "borderTopStartRadius",
        "borderTopEndRadius",
        "borderBottomLeftRadius",
        "borderBottomRightRadius",
        "borderBottomStartRadius",
        "borderBottomEndRadius",
        "borderStyle",
        "opacity",
        "elevation",
        "color",
        "fontFamily",
        "fontSize",
        "fontStyle",
        "fontWeight",
        "fontVariant",
        "textShadowOffset",
        "textShadowRadius",
        "textShadowColor",
        "letterSpacing",
        "lineHeight",
        "textAlign",
        "textAlignVertical",
        "includeFontPadding",
        "textDecorationLine",
        "textDecorationStyle",
        "textDecorationColor",
        "textTransform",
        "writingDirection"
      ]
          at accessible (/home/circleci/react-native/Libraries/Text/Text.js:35:5)

      185 |     };
      186 |
    > 187 |     const instance = render.create(<Text style={style} />);
          |                                    ^
      188 |
      189 |     expect(instance.toJSON()).toMatchInlineSnapshot(`
      190 |       <RCTText

      at printWarning (node_modules/react/cjs/react-jsx-runtime.development.js:87:30)
      at error (node_modules/react/cjs/react-jsx-runtime.development.js:61:7)
      at checkPropTypes (node_modules/react/cjs/react-jsx-runtime.development.js:631:11)
      at validatePropTypes (node_modules/react/cjs/react-jsx-runtime.development.js:1164:7)
      at jsxWithValidation (node_modules/react/cjs/react-jsx-runtime.development.js:1284:7)
      at Object.jsxWithValidationDynamic [as jsx] (node_modules/react/cjs/react-jsx-runtime.development.js:1301:12)
      at Object.<anonymous> (Libraries/Text/__tests__/Text-test.js:187:36)

This comment has been minimized.

Copy link
@necolas

necolas Nov 23, 2022

Contributor

I noticed that too and was surprised to see propTypes is still a thing.

This comment has been minimized.

Copy link
@NickGerleman

NickGerleman Nov 26, 2022

Contributor

I know removing them caused issues before because others were still relying on them, but I think we could maybe offer the accessors without enforcing them?

As is I think this means we will get a console.error() when using any of the new props added in this release to Image or Text. That… feels like something we should resolve before 0.71 comes out.

Separately we should update our Jest preset to fail a test on console.error(), which would have surfaced this.

This comment has been minimized.

Copy link
@NickGerleman

NickGerleman Nov 26, 2022

Contributor

Or I guess folks could be referencing the propTypes field in their own code.

So I think the solution would have to be restoring the package to the repo, then updating it with new props, if we wanted to keep supporting it.


/**
* Returns false until the first time `newValue` is true, after which this will
* always return true. This is necessary to lazily initialize `Pressability` so
Expand Down
24 changes: 12 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -433,44 +433,44 @@ module.exports = {
},
// Deprecated Prop Types
get ColorPropType(): $FlowFixMe {
invariant(
false,
'ColorPropType has been removed from React Native, along with all ' +
console.error(
'ColorPropType will be removed from React Native, along with all ' +
'other PropTypes. We recommend that you migrate away from PropTypes ' +
'and switch to a type system like TypeScript. If you need to ' +
'continue using ColorPropType, migrate to the ' +
"'deprecated-react-native-prop-types' package.",
);
return require('deprecated-react-native-prop-types').ColorPropType;
},
get EdgeInsetsPropType(): $FlowFixMe {
invariant(
false,
'EdgeInsetsPropType has been removed from React Native, along with all ' +
console.error(
'EdgeInsetsPropType will be removed from React Native, along with all ' +
'other PropTypes. We recommend that you migrate away from PropTypes ' +
'and switch to a type system like TypeScript. If you need to ' +
'continue using EdgeInsetsPropType, migrate to the ' +
"'deprecated-react-native-prop-types' package.",
);
return require('deprecated-react-native-prop-types').EdgeInsetsPropType;
},
get PointPropType(): $FlowFixMe {
invariant(
false,
'PointPropType has been removed from React Native, along with all ' +
console.error(
'PointPropType will be removed from React Native, along with all ' +
'other PropTypes. We recommend that you migrate away from PropTypes ' +
'and switch to a type system like TypeScript. If you need to ' +
'continue using PointPropType, migrate to the ' +
"'deprecated-react-native-prop-types' package.",
);
return require('deprecated-react-native-prop-types').PointPropType;
},
get ViewPropTypes(): $FlowFixMe {
invariant(
false,
'ViewPropTypes has been removed from React Native, along with all ' +
console.error(
'ViewPropTypes will be removed from React Native, along with all ' +
'other PropTypes. We recommend that you migrate away from PropTypes ' +
'and switch to a type system like TypeScript. If you need to ' +
'continue using ViewPropTypes, migrate to the ' +
"'deprecated-react-native-prop-types' package.",
);
return require('deprecated-react-native-prop-types').ViewPropTypes;
},
};

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
"abort-controller": "^3.0.0",
"anser": "^1.4.9",
"base64-js": "^1.1.2",
"deprecated-react-native-prop-types": "^2.3.0",
"event-target-shim": "^5.0.1",
"invariant": "^2.2.4",
"jest-environment-node": "^29.2.1",
Expand Down
13 changes: 11 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4145,6 +4145,15 @@ depd@~1.1.2:
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=

deprecated-react-native-prop-types@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-2.3.0.tgz#c10c6ee75ff2b6de94bb127f142b814e6e08d9ab"
integrity sha512-pWD0voFtNYxrVqvBMYf5gq3NA2GCpfodS1yNynTPc93AYA/KEMGeWDqqeUB6R2Z9ZofVhks2aeJXiuQqKNpesA==
dependencies:
"@react-native/normalize-color" "*"
invariant "*"
prop-types "*"

deprecation@^2.0.0, deprecation@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
Expand Down Expand Up @@ -5548,7 +5557,7 @@ interpret@^1.0.0:
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=

invariant@^2.2.4:
invariant@*, invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
Expand Down Expand Up @@ -7848,7 +7857,7 @@ prompts@^2.0.1, prompts@^2.4.0:
kleur "^3.0.3"
sisteransi "^1.0.5"

prop-types@^15.8.1:
prop-types@*, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
Expand Down

0 comments on commit b966d29

Please sign in to comment.