Add item to property with array value in custom component
Let's say I have the following component in React
const SpecializedTextField= props => {
return (
<TextField
{...props}
validate={[isNumber, isPositiveNumber]}
/>
);
};
And I want to add another validation check:
<SpecializedTextField validate={[isRequired]} />
This will add validation to the TextField so that the result is validate={[isRequired, isNumber, isPositiveNumber]}
Of course, I could just extract both arrays and concatenate them. But is there a clean way (some syntactic sugar) to add the two properties together in es6 / react?
source to share
Of course, I could just extract both arrays and concatenate them.
This is pretty much what you need to do, but it's pretty succinct with the extension:
const SpecializedTextField= props => {
const {validate = [], ...other} = props;
return (
<TextField
{...other}
validate={[isNumber, isPositiveNumber, ...validate]}
/>
);
};
Of course, this assumes that either you don't get isNumber
it isPositive
in the prop validate
, or that having duplicates is not a problem. It also creates and propagates an empty array if there is no validate
prop.
If these assumptions are not valid and / or the creation and propagation of an empty array bothers you (is it me, microopt or not), you will need to create a unique set that you could do yourself or through Set
. Maybe:
const specializedTextFieldValidations = [isNumber, isPositiveNumber];
const SpecializedTextField = props => {
let {validate = specializedTextFieldValidations, ...other} = props;
if (validate !== specializedTextFieldValidations) {
validate = [...new Set([...specializedTextFieldValidations, ...validate]).values()];
}
return (
<TextField {...other} validate={validate} />
);
};
(Too bad, the constructor Set
only accepts one Iterable
, not a number ...)
Speaking of micro-optimization, it turns out that propagation is currently much slower thanconcat
that, so
validate = [...new Set([...specializedTextFieldValidations, ...validate]).values()];
could be better written as
validate = [...new Set(specializedTextFieldValidations.concat(validate)).values()];
source to share
In addition to @TJ Crowder's answer, you don't need to destroy props in order to extract validate
and other
. validate
prop has the same name and will be overridden due to the order of the attribute in jsx:
const SpecializedTextField= props => {
return (
<TextField
{...props}
validate={[...props.validate, isNumber, isPositiveNumber]}
/>
);
};
SpecializedTextField.defaultProps = {
validate: [],
};
source to share