Reputation: 3039
How do i accept conditional attributes in react.js
below is my search component, I want the InputGroup to have a onSubmit attribute if the onSubmit function is passed and an onChange attribute if an onChange function is passed
class QueryBar extends PureComponent {
render() {
const { placeholder, leftIcon, onSubmit, onChange, width } = this.props;
return (
<form
style={{ width }}
onSubmit={e => {
e.preventDefault();
onSubmit(e.target[0].value);
}}
>
<InputGroup
placeholder={placeholder}
width={width}
leftIcon="search"
rightElement={
<Button
type="submit"
icon={leftIcon}
minimal={true}
intent={Intent.PRIMARY}
/>
}
/>
</form>
);
}
}
QueryBar.propTypes = {
width: PropTypes.number,
placeholder: PropTypes.string,
leftIcon: PropTypes.oneOfType(['string', 'element']),
onSubmit: PropTypes.func
};
QueryBar.defaultProps = {
placeholder: 'Search...',
leftIcon: 'arrow-right',
width: 360
};
export default QueryBar;
Upvotes: 0
Views: 1961
Reputation: 7555
jsx elements can also accept objects. Initialize an object that contains information for both situations and then add a conditional to add a function if it exists in the props passed in.
render() {
const { placeholder, leftIcon, onSubmit, onChange, width } = this.props;
const inputGroupProps = {
placeholder,
width,
leftIcon: 'search',
rightElement: (
<Button
type="submit"
icon={leftIcon}
minimal={true}
intent={Intent.PRIMARY}
/>
)
}
if (onChange) {
inputGroupProps.onChange = onChange
}
if (onSubmit) {
inputGroupProps.onSubmit = onSubmit
}
return (
<form
style={{ width }}
onSubmit={e => {
e.preventDefault();
onSubmit(e.target[0].value);
}}
>
<InputGroup {...inputGroupProps} />
</form>
);
}
While I do not recommend it, adding both are technically OK because a prop that isn't passed in from the parent but destructured, will be undefined
. I don't recommend this because it is not expressive and will probably confuse you in the future
<InputGroup
placeholder={placeholder}
width={width}
leftIcon="search"
rightElement={
<Button
type="submit"
icon={leftIcon}
minimal={true}
intent={Intent.PRIMARY}
/>
}
onChange={onChange} // will be undefined and have no behavior if parent does not pass an onChange prop
onSubmit={onSubmit} // same for this one
/>
Upvotes: 1
Reputation: 2938
I would do this:
The idea is to have an Object optionalProps
, an empty object for any possible conditional properties, when a property exists, we add it to the object, then, in the InputGroup
component we apply it as {...optionalProps}
which will extract any added properties to the object, and return nothing if null.
we could follow another approach: onChange={onChange && onChange}
But, note This will return false
as a value for cases where onChange
doesn't exist.
render() {
const { placeholder, leftIcon, onSubmit, onChange, width } = this.props;
let optionalProps = {};
if(onChange){
optionalProps['onChange'] = onChange;
}
if(onSubmit){
optionalProps['onSubmit'] = onSubmit;
}
return (
<form
style={{ width }}
onSubmit={e => {
e.preventDefault();
onSubmit(e.target[0].value);
}}
>
<InputGroup
placeholder={placeholder}
width={width}
leftIcon="search"
{...optionalProps}
rightElement={
<Button
type="submit"
icon={leftIcon}
minimal={true}
intent={Intent.PRIMARY}
/>
}
/>
</form>
);
}
Upvotes: 0
Reputation: 5054
You can pass null if its not there i.e :
<InputGroup
placeholder={placeholder}
width={width}
leftIcon="search"
onChange={onChangeFn?onChangeFn:null}
onSubmit={onSubmitFn ? onSubmitFn : null}
rightElement={
<Button
type="submit"
icon={leftIcon}
minimal={true}
intent={Intent.PRIMARY}
/>
}
/>
It will make sure if function is there then call function otherwise it will not anything.
Upvotes: 0