Conditionally adding attributes and props in React
4 min read
Sometimes, we need to add attributes to elements or props to React components, but only when certain conditions are met. Other times, we don't want to add those attributes or props.
How can we conditionally add props or attributes? We will look at 3 quick and easy approaches that include using an inline conditional statement, an if statement, and the spreading of props.
Option 1: An inline conditional statement
Let's consider a Product
component that receives an isMember
prop. It will need to disable the "Buy Now" button if the isMember
prop is false
. Non-members cannot buy products.
In this approach, we will use an inline conditional statement directly on the disabled attribute of the button
.
type Props = {
isMember: boolean;
};
const Product = ({ isMember }: Props) => {
return (
<div>
<h1>Product</h1>
<button disabled={!isMember}>
Buy Now
</button>
</div>
);
}
export default function App() {
return <Product isMember={false} />;
}
If isMember
is true
, the button
is not disabled. However, if isMember
is false
, the button
will be disabled.
React will not pass a value to an element's prop or attribute if that value is falsy. The disabled attribute will not be included on the button
tag when !isMember
is falsy. Falsy values are null
, undefined
, and false
.
The condition used here is !isMember
, which means that when isMember
is true
, the expression !isMember
will be false
. Thus, the button
will not contain a disabled attribute when isMember
is true
.
Option 2: An if statement
Using inline conditional statements directly on attributes is fine if the conditional statement is short and simple. However, more complex conditional statements become harder to read and test when they are inline. Also, having too many inline conditional statements can make your React component confusing and messy.
When they start adding up and becoming more complex, it's best to start using if statements outside of the component's return
statement.
type Props = {
isMember: boolean;
status: string;
};
const Product = ({ isMember, status }: Props) => {
let disabled = undefined;
if (!isMember || status === 'sold-out') {
disabled = true;
}
return (
<div>
<h1>Product</h1>
<button disabled={disabled}>
Buy Now
</button>
</div>
);
}
export default function App() {
return <Product isMember={false} status='sold-out' />;
}
To show the effectiveness of this approach, we purposely complicated the conditional statement a bit. Not only are we checking for non-members, but we are now also checking for a "sold-out" status. When either of these conditions occur, we want to disable our "Buy Now" button.
We used a local component-level variable called disabled
and assigned it to the disabled button attribute. When isMember
is false
, or when the status
is "sold-out", the disabled
variable will be true
, disabling the button
.
We initialized the disabled
variable with undefined
, which is one of the falsy values that we saw above, but we could have also used false
or null
.
Option 3: Spreading attributes or props
If you have to configure multiple attributes for an element or multipe props for a React comoponent, this next approach works best.
We'll create a buttonProps
object and add in all the button attributes that we want to configure. We'll then spread the buttonProps
object into the button
element, which will set all the button attributes to the values that we assigned within buttonProps
.
type Props = {
isMember: boolean;
status: string;
};
type ButtonProps = {
type: 'submit' | 'reset' | 'button';
disabled: boolean;
};
const Product = ({ isMember, status }: Props) => {
let buttonProps: ButtonProps = {
type: 'button',
disabled: false,
};
if (!isMember || status === 'sold-out') {
buttonProps = {
...buttonProps,
disabled: true,
};
}
return (
<div>
<h1>Product</h1>
<button {...buttonProps}>Buy Now</button>
</div>
);
};
export default function App() {
return <Product isMember={false} status='sold-out' />;
}
When isMember
is false
, or when the status
is "sold-out", we spread in the original buttonProps
object and just overwrite the attributes that need to be changed. In this case, the only attribute that needed to be updated was disabled
. We set it to true
to disable the button when any of the two conditions are met.
Conclusion
We learned three ways to conditionally add attributes to elements like button
. These three approaches also work for adding props to React components.
In the examples above, we could replace button
with a custom React Button
component, but the ways that we can conditionlly add props to Button
would be exactly the same.
- Use inline statements directly on the attribute or prop for simple conditions, but don't use too many inline statements in one component.
- Use if statements for complex conditions.
- Consider spreading when multiple attributes or props need to configured.