I have a use case where I need to write a custom React PropType
validator. Within that checker I want to do two things: 1) validate that the prop names inside the object, which are dynamically generated, are all md5 hashes, and 2) validate the "shape" of the object connected to each prop.
Question #1 I have figured out; #2 is eluding me a bit. Here's some code to illustrate:
Say I have an object like this:
{
key1: {
byHash: {
'<some md5 hash>': { ... }
}
},
key2: {
byHash: {
'<some md5 ash>': { ... }
}
}
}
When checking this object I want to make sure that the keys are indeed md5 hashes, and then I want to ensure the correctness of the keys and their values in each of the objects assigned to key1
and key2
. Let's say, in addition, I've created a validator function like so:
const validObjShape = PropTypes.shape({
someString: PropTypes.string.isRequired,
someBoolean: PropTypes.bool
});
Then I write my custom validator function:
const validCustomProp = (props, propName, componentName) => {
const obj = props[propName];
if (!isObject(obj)) {
return new Error(
//eslint-disable-next-line
'Invalid prop `' + propName + '`of type `' + typeof obj + '` supplied to ' +
'`' + componentName + '`, expected an object.'
);
}
if (isEmpty(obj)) {
return null;
}
forEach(obj, (v, k) => {
const isMD5 = (/[a-fA-F0-9]{32}/).test(k);
if (!isMD5) {
throw new Error(
//eslint-disable-next-line
'Invalid dynamic key on `' + propName + '`. All keys ' +
'on this object should be md5 hashes, but we found `' + k + '` instead.'
);
}
});
// Here I want to somehow validate each object on `obj`. Something like:
// forEach(obj, (v, k) => {
// const err = validObjShape(props[propName], k, componentName);
// if (err) {
// // throw some err...
// }
// }
return null;
};
My question -- as noted in-line above -- can I use the validObjShape
that I created above to validate the shape of the objects nested within obj
. I think that this calling of a validator fn directly will be disallowed in v16 of React (see this post ). So how can this now be achieved?
PropTypes
directly from React is deprecated - not the use of PropTypes
themselves. As it says in the docs, declaring PropTypes
is fine , just use the prop-types library instead.
So,
const apiShape = React.PropTypes.shape({
body: customValidator,
statusCode: React.PropTypes.number.isRequired
}).isRequired;
simply changes to
import PropTypes from 'prop-types';
const apiShape = React.PropTypes.shape({
body: customValidator,
statusCode: PropTypes.number.isRequired
}).isRequired;
And the customValidator
doesn't have to change.
You can verify this yourself in the source: ElementCreation => ElementValidation in DEV mode => Validating prop types => calling checkPropTypes which has simply been moved here
React strongly believes in type safety and deprecating PropTypes
altogether seems very unlikely. It is still present in the docs (from the master)
This is new behavior, and you will only encounter it when you migrate from React.PropTypes to the prop-types package.
So the following is deprecated
Object.keys(props[propName]).forEach(k => {
// const v = props[propName][k];
const isMD5 = (/[a-fA-F0-9]{32}/).test(k);
if (!isMD5) {
return new Error(
'Not an md5'
);
}
return validObjShape(props[propName], k, componentName);
});
Instead use checkPropTypes
:
const validObjShape = PropTypes.shape({
someString: PropTypes.string.isRequired,
someBoolean: PropTypes.bool
});
const validCustomProp = (props, propName, componentName) => {
Object.keys(props[propName]).forEach(k => {
const v = props[propName][k];
const isMD5 = (/[a-fA-F0-9]{32}/).test(k);
if (!isMD5) {
return new Error(
'Not an md5'
);
}
PropTypes.checkPropTypes({ [k]: validObjShape }, { [k]: v }, propName, componentName);
});
return null;
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.