Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to override isRequired #339

Closed
dkreft opened this issue Mar 17, 2021 · 6 comments
Closed

Add ability to override isRequired #339

dkreft opened this issue Mar 17, 2021 · 6 comments

Comments

@dkreft
Copy link

dkreft commented Mar 17, 2021

When passing props from one component to another, I like to have a single source of truth for my propTypes--the component that actually uses the prop:

// File: A.jsx

import PropTypes from 'prop-types'

import B from './B'


export default function A({ className, foo }) {
  return (
    <div className={ className }>
      <B foo={ foo } />
    </div>
  )
}

A.propTypes = {
  className: PropTypes.string,
  foo: B.propTypes.foo,
}
// File: B.jsx

import PropTypes from 'prop-types'


export default function B({ foo }) {
  return ( /* blah blah blah */ )
}

B.propTypes = {
  foo: PropTypes.string.isRequired,
}

In this case, the foo property on A is mandatory...which is great. Well, that is until I want to make foo optional on A because I'm declaring a default value for it:

A.propTypes = {
  className: PropTypes.string,
  // Warnings ensue...
  foo: B.propTypes.foo,
}

A.defaultProps = {
  foo: 'default value provided by A',
}

What I'd like to be able to do is override the isRequired flag, perhaps like this:

A.propTypes = {
  className: PropTypes.string,
  foo: B.propTypes.foo.optional,   // <=== `optional` overrides `isRequired`
}

If there's some other reasonable way around this problem, I'm all ears.

@ljharb
Copy link
Collaborator

ljharb commented Mar 18, 2021

If foo is required for B, then it's absolutely required for A in your example. In other words, omitting it on A will be a bug when it gets to B and isn't present, so it should be required for both.

Do you have another example?

@dkreft
Copy link
Author

dkreft commented Mar 18, 2021

@ljharb, I think you may have missed A.defaultProps in the third code block:

Screen Shot 2021-03-18 at 2 20 21 PM

In that case, it is optional for A by virtue of the defaultProps, but of course, prop-types still recognizes it as a mandatory property in A because there's no way to override the isRequired...which is the issue that I'm seeking to resolve.

@ljharb
Copy link
Collaborator

ljharb commented Mar 18, 2021

I could still pass foo as null and it would break, because it should, in fact, be required on A.

@dkreft
Copy link
Author

dkreft commented Mar 18, 2021

I feel like maybe we're speaking past each other.

I'm trying to figure out a way to make the param mandatory for B but optional for A, but it sounds like you're talking about the status quo.

If you have a recommendation for how to achieve this, I'm all ears.

@ljharb
Copy link
Collaborator

ljharb commented Mar 18, 2021

This is how:

A.propTypes = {
  foo: B.propTypes.foo, // required
};
A.defaultProps = {
  foo: 'some default'
};

This way, foo is required, but because it is also defaulted, the user doesn't have to pass it - but if they pass null it's invalid, which is correct.

@dkreft
Copy link
Author

dkreft commented Mar 19, 2021

Hrmm. Well, then...I suppose I'll just crawl back under the rock out from which I came.

image

@dkreft dkreft closed this as completed Mar 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants