facebook / prop-types

Runtime type checking for React props and similar objects
MIT License
4.48k stars 358 forks source link

Upgrading `defaultProps` to use JavaScript default parameters shows isRequired errors #413

Open missalyss opened 2 months ago

missalyss commented 2 months ago

React version: 18.3.1 Prop-Types version: 15.8.1

Context:

Currently using Prop-Types for documenting UI pattern library components as well as for in-console errors to ensure consumers of component library use important props (like aria-label, for example).

Problem:

Recent version of react has deprecated defaultProps for functional components. The deprecation is flagged as a "warning" in the console during development (but is not type warning, but type error). These errors are disruptive to development as they take up a lot of space for every instance and since they're type error, not easily ignored or filtered out.

 Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.
image

As instructed, I removed defaultProps and put the default value in as a default parameter in props like so:

const Icon = ({
  viewBox = '0 0 24 24',
}) => {
    ...
};

Icon.propTypes = {
  viewBox: PropTypes.string.isRequired,
};

export default Icon;

The component renders and behaves correctly. However, the following error is then displayed in my console:

Failed prop type: The prop `viewBox` is marked as required in `Icon`, but its value is `undefined`.
image

Relevant code: https://github.com/facebook/prop-types/blob/main/factoryWithTypeCheckers.js#L211

Expected: migrating to default parameters gets rid of defaultProps error while isRequired reads default parameters as default props.

Actual: isRequired does not read default parameters as default props but sees that the props are undefined.

ljharb commented 2 months ago

As it should - you can't use default arguments if you're using propTypes, they're incompatible. (it is impossible to introspect on default arguments at runtime reliably, which is one of the many ways propTypes are superior)

(React 19, which is not actually released yet, is the one that removes propTypes support)

missalyss commented 2 months ago

@ljharb Thanks for the response. Any literature to read about how/why the incompatibility? Or am I hearing that PropTypes is being deprecated entirely in favor of TypeScript?

ljharb commented 2 months ago

Yes, that was the react team’s decision.

funktr0n commented 1 month ago

@ljharb Running into this as well. So just for clarity, as of React 19's release, this project will no longer function at all when used on function components e.g. MyFunctionComponent.propTypes = ...?

If so, do you have any recommendations on how to move forward for teams that don't want to adopt TypeScript?

ljharb commented 1 month ago

Yes, that’s right.

No, unfortunately, the react team has decided that TypeScript is the way, so you’ll basically have to use tsc somehow - either via jsdoc comments in your JS, or by converting your jsx to tsx.

funktr0n commented 1 month ago

Ok, I appreciate the response, and I definitely agree that that is indeed unfortunate.