Reputation: 2639
I've got a prop on a ReactJS Component that's either null or an Immutable Map.
At the bottom of my widget if I write:
MyComponent.propTypes = {
myMap: React.PropTypes.instanceOf(Immutable.Map)
};
I am leaving this open to the possibility of being null, undefined, or a Map.
How can I make this required and of type null or map only?
https://facebook.github.io/react/docs/typechecking-with-proptypes.html
I see this example but I do not know how to tailor the syntax to my needs or if it is even possible.
Edit: If a property is null, then it is still there but undefined means that it's not been included altogether.
For example:
<Component id={1} data={null} />
<Component id={2} data={Immutable.Map()} />
<Component id={3} />
Upvotes: 40
Views: 43018
Reputation: 2691
You can use the prop type without .isRequired
.
MyComponent.propTypes = {
name: PropTypes.string
}
And define the null
value in the defaultProps
MyComponent.defaultProps = {
name: null
}
Upvotes: 3
Reputation: 6900
To help with this quite common issue, I created a clean and fully-typed wrapper called better-prop-types:
import BetterPropTypes from 'better-prop-types'
// ...
MyComponent.propTypes = {
myMap: BetterPropTypes.PropTypes.instanceOf(Immutable.Map).isRequiredButNullable
}
Upvotes: 0
Reputation: 6373
It is possible to use PropTypes.oneOf([null]).isRequired
. It should allow null, and nothing else. You can combine that with any other type:
PropTypes.oneOfType([
PropTypes.string.isRequired,
PropTypes.oneOf([null]).isRequired,
]).isRequired
Edit: I just had this prop type fail for me when given a null prop using prop-types 15.7.2, so I'm not sure this works anymore (if it ever did?). I reverted to allowing both undefineds and nulls by just not using isRequired.
Upvotes: 24
Reputation: 21
Maybe too late but this work for me, is a custom propType. More info in react docs: https://reactjs.org/docs/typechecking-with-proptypes.html#proptypes
static propTypes = {
myMap: function(props, propName, componentName) {
if (props[propName] !== null && !(props[propName] instanceof Immutable.Map)) {
return new Error(
'Invalid prop `' + propName + '` supplied to `' + componentName + '`. Expected null or Immutable.Map, but received ' + typeof props[propName] + '. Validation failed.'
)
}
},
}
Upvotes: 2
Reputation: 6386
I had similar problem and that's how I got here. I found a solution that's good enough for me, so I might as well share it.
In short, I removed .isRequired
and set defaultProps
to null
.
I wanted something like this:
// this won't work, because `PropTypes.null` doesn't exists!
MyComponent.propTypes = {
item: PropTypes.oneOfType([ItemPropTypesShape, PropTypes.null]).isRequired,
};
// this also won't work!
MyComponent.propTypes = {
item: PropTypes.oneOfType([ItemPropTypesShape, PropTypes.instanceOf(null)]).isRequired,
};
The null is always treated as error when prop is required.
I ended up doing this:
MyComponent.propTypes = {
item: ItemPropTypesShape,
};
MyComponent.defaultProps = {
item: null,
};
If PropTypes is all we have, this works for me!
Upvotes: 14
Reputation: 42460
This requirement seems to be unsupported with the current version of React.
Refer to React issue #2166 for more details. This issue discusses the possibility of an isRequiredOrNull
property in addition to isRequired
. Bottom line:
I wouldn't expect there to be further changes to PropTypes. Flow has become much more mature recently, and from what I heard from the React team, it is the longer term solution to type checking. This puts PropTypes into the same "compatibility" bucket in terms of priorities—like createClass or React addons, they are still supported, but only with bugfixes and performance improvements, without adding new features or changing the API.
In other words, if you require more sophisticated type checking, use Flow instead.
Upvotes: 11