Skip to content

Commit

Permalink
Remove JSX propTypes validation (#28328)
Browse files Browse the repository at this point in the history
This removes the remaining `propTypes` validation calls, making
declaring `propTypes` a no-op. In other words, React itself will no
longer validate the `propTypes` that you declare on your components.

In general, our recommendation is to use static type checking (e.g.
TypeScript). If you'd like to still run propTypes checks, you can do so
manually, same as you'd do outside React:

```js
import checkPropTypes from 'prop-types/checkPropTypes';

function Button(props) {
  checkPropTypes(Button.propTypes, prop, 'prop', Button.name)
  // ...
}
```

This could be automated as a Babel plugin if you want to keep these
checks implicit. (We will not be providing such a plugin, but someone in
community might be interested in building or maintaining one.)

DiffTrain build for commit 353ecd0.
  • Loading branch information
gaearon committed Feb 21, 2024
1 parent c825387 commit 81206cb
Show file tree
Hide file tree
Showing 9 changed files with 18 additions and 537 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25696,7 +25696,7 @@ if (__DEV__) {
return root;
}

var ReactVersion = "18.3.0-canary-4ea424e63-20240220";
var ReactVersion = "18.3.0-canary-353ecd051-20240221";

// Might add PROFILE later.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9176,7 +9176,7 @@ var devToolsConfig$jscomp$inline_1014 = {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "18.3.0-canary-4ea424e63-20240220",
version: "18.3.0-canary-353ecd051-20240221",
rendererPackageName: "react-test-renderer"
};
var internals$jscomp$inline_1195 = {
Expand Down Expand Up @@ -9207,7 +9207,7 @@ var internals$jscomp$inline_1195 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-canary-4ea424e63-20240220"
reconcilerVersion: "18.3.0-canary-353ecd051-20240221"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1196 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9604,7 +9604,7 @@ var devToolsConfig$jscomp$inline_1056 = {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "18.3.0-canary-4ea424e63-20240220",
version: "18.3.0-canary-353ecd051-20240221",
rendererPackageName: "react-test-renderer"
};
var internals$jscomp$inline_1236 = {
Expand Down Expand Up @@ -9635,7 +9635,7 @@ var internals$jscomp$inline_1236 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-canary-4ea424e63-20240220"
reconcilerVersion: "18.3.0-canary-353ecd051-20240221"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1237 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<20a889fc4c8eaee85875c7091bc5ea65>>
* @generated SignedSource<<a9c49bc89f61d32aa1bc5a10d3664a01>>
*/

"use strict";
Expand Down Expand Up @@ -443,111 +443,6 @@ if (__DEV__) {
return "";
}

var loggedTypeFailures = {};
var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;

function setCurrentlyValidatingElement$1(element) {
{
if (element) {
var owner = element._owner;
var stack = describeUnknownElementTypeFrameInDEV(
element.type,
owner ? owner.type : null
);
ReactDebugCurrentFrame$1.setExtraStackFrame(stack);
} else {
ReactDebugCurrentFrame$1.setExtraStackFrame(null);
}
}
}

function checkPropTypes(
typeSpecs,
values,
location,
componentName,
element
) {
{
// $FlowFixMe[incompatible-use] This is okay but Flow doesn't know it.
var has = Function.call.bind(hasOwnProperty);

for (var typeSpecName in typeSpecs) {
if (has(typeSpecs, typeSpecName)) {
var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
// fail the render phase where it didn't fail before. So we log it.
// After these have been cleaned up, we'll let them throw.

try {
// This is intentionally an invariant that gets caught. It's the same
// behavior as without this statement except with a better message.
if (typeof typeSpecs[typeSpecName] !== "function") {
// eslint-disable-next-line react-internal/prod-error-codes
var err = Error(
(componentName || "React class") +
": " +
location +
" type `" +
typeSpecName +
"` is invalid; " +
"it must be a function, usually from the `prop-types` package, but received `" +
typeof typeSpecs[typeSpecName] +
"`." +
"This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`."
);
err.name = "Invariant Violation";
throw err;
}

error$1 = typeSpecs[typeSpecName](
values,
typeSpecName,
componentName,
location,
null,
"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"
);
} catch (ex) {
error$1 = ex;
}

if (error$1 && !(error$1 instanceof Error)) {
setCurrentlyValidatingElement$1(element);

error(
"%s: type specification of %s" +
" `%s` is invalid; the type checker " +
"function must return `null` or an `Error` but returned a %s. " +
"You may have forgotten to pass an argument to the type checker " +
"creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " +
"shape all require an argument).",
componentName || "React class",
location,
typeSpecName,
typeof error$1
);

setCurrentlyValidatingElement$1(null);
}

if (
error$1 instanceof Error &&
!(error$1.message in loggedTypeFailures)
) {
// Only monitor this failure once because there tends to be a lot of the
// same error.
loggedTypeFailures[error$1.message] = true;
setCurrentlyValidatingElement$1(element);

error("Failed %s type: %s", location, error$1.message);

setCurrentlyValidatingElement$1(null);
}
}
}
}
}

var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
var REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference");
Expand Down Expand Up @@ -950,8 +845,6 @@ if (__DEV__) {

if (type === REACT_FRAGMENT_TYPE) {
validateFragmentProps(element);
} else {
validatePropTypes(element);
}

return element;
Expand Down Expand Up @@ -1178,71 +1071,6 @@ if (__DEV__) {
}
}

var propTypesMisspellWarningShown = false;
/**
* Given an element, validate that its props follow the propTypes definition,
* provided by the type.
*
* @param {ReactElement} element
*/

function validatePropTypes(element) {
{
var type = element.type;

if (type === null || type === undefined || typeof type === "string") {
return;
}

if (type.$$typeof === REACT_CLIENT_REFERENCE) {
return;
}

var propTypes;

if (typeof type === "function") {
propTypes = type.propTypes;
} else if (
typeof type === "object" &&
(type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here.
// Inner props are checked in the reconciler.
type.$$typeof === REACT_MEMO_TYPE)
) {
propTypes = type.propTypes;
} else {
return;
}

if (propTypes) {
// Intentionally inside to avoid triggering lazy initializers:
var name = getComponentNameFromType(type);
checkPropTypes(propTypes, element.props, "prop", name, element);
} else if (
type.PropTypes !== undefined &&
!propTypesMisspellWarningShown
) {
propTypesMisspellWarningShown = true; // Intentionally inside to avoid triggering lazy initializers:

var _name = getComponentNameFromType(type);

error(
"Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?",
_name || "Unknown"
);
}

if (
typeof type.getDefaultProps === "function" &&
!type.getDefaultProps.isReactClassApproved
) {
error(
"getDefaultProps is only used on classic React.createClass " +
"definitions. Use a static property named `defaultProps` instead."
);
}
}
}

var jsxDEV = jsxDEV$1;

exports.Fragment = REACT_FRAGMENT_TYPE;
Expand Down
Loading

0 comments on commit 81206cb

Please sign in to comment.