I've been searching everywhere and can't find an answer to my question. So I want a conditional attribute which is only displayed on certain conditions, example:
<Button {this.state.view === 'default' && 'active'}></Button>
As you can see I only want to indicate the button active if the this.state.view
is equal to default. However, I get Unexpected token, error...
But when I try to put an attribute before it, for example:
<Button isActive={this.state.view === 'default' && 'active'}></Button>
It passes the syntax error and displays fine but this is not what I wanted to achieve.
How can I fix this? And what could be the reason behind it not passing?
So I just found out that in react-bootstrap
the property active
is a shorthand of active=true
so I solved it using
<Button active={this.state.view === 'default'}></Button>
So In case, someone encounters this problem I'm leaving it here. However, I still want to know why the conditional attribute is failing without enclosing it inside a prop-like syntax, example:
This:
active={this.state.view === 'default'}
Versus
{this.state.view === 'default' && 'active'}
You can use any logic and conditionals in order to build the object. You will most commonly use the ternary operator to add conditional attributes to an element in React.
Spread Operator This method is one of my favorites when it comes to conditional props. The Spread Operator is used when passing all the properties of an object or all the elements of an array to a React Component. Here, I have used the attributes object to store all the required attributes of the input field.
To set a data attribute on an element in React, set the attribute directly on the element, e.g. <button data-test-id="my-btn"> or use the setAttribute() method, e.g. el. setAttribute('data-foo', 'bar') . You can access the element on the event object or using a ref . Copied!
We can embed any JavaScript expression in JSX by wrapping it in curly braces. But only expressions not statements, means directly we can not put any statement (if-else/switch/for) inside JSX.
First of all, JSX is just a syntactic sugar for React.createElement
. So, it may look like, but, in reality, you don't specify html attributes
: in fact, you are always passing props
.
For instance, the JSX code <input type="button" value="My button" />
is transpiled into React.createElement('input',{type:'button',value:'My Button'})
. And, when necessary, React engine renders this React Element
to the DOM as a HTML element.
That said, we have that JSX transpiles a prop
without a value as true (check docs). For instance: <Button active></Button>
is transpiled to React.createElement(Button, { active: true });
.
But, we know that HTML5 specification does not accept attribute=true
(as pointed here). For instance: <button disabled=true></button>
is invalid. The correct is <button disabled></button>
.
So, to render the HTML element to the DOM, React considers only props
that are valid attributes
(if not, the attribute is not rendered). Check all supported html attributes. And, then, finally, if it's a boolean attribute, it removes the true/false value, rendering it properly.
For instance: <button active={true}></button>
is transpiled to React.createElement("button", { active: true });
and then React renders to the DOM <button></button>
, because there is no active
attribute in HTML specification for the <button/>
tag (is not in the supported attributes list).
But <button disabled={true}></button>
is transpiled to React.createElement("button", { disabled: true });
and React renders to the DOM <button disabled></button>
.
I just said that to clarify your case.
You're trying to pass an active
prop to the Button
component (first letter uppercase means that's a React component: there is a React Component called Button
handled somewhere in your code).
That means:
<Button active></Button>
is transpiled to React.createElement(Button, { active: true });
and
<Button active={true}></Button>
is transpiled to React.createElement(Button, { active: true });
The same thing!
So, if you want to do a conditional prop
, you can simply do something like that:
<Button active={this.state.view === 'default'}></Button>
You have a condition inside brackets. Means that, if your this.state.view
is equal to default
(true), active
prop will be passwed down to the component with the true
value. If not equal, with the false
value.
Button
Component, then, must someway handle this active
prop. It can render the button
element and, for instance, change it's style, pass the disabled
prop... I created a fiddle to demonstrate this: https://jsfiddle.net/mrlew/5rsx40gu/
Actually, I guess it is a duplicated question that I answered it in this link sometimes ago. for this specific post, there is no need condition prop for a boolean value, because it works well like below:
const { booleanValue } = this.props;
return (
<input checked={booleanValue} />
);
Or make your own boolean value:
const booleanValue = someThing === someOtherThing;
return (
<input checked={booleanValue} />
);
Both of them work well, because when the booleanValue
is false
, react
doesn't see the active
prop, hence it does not exist, unless you pass checked
prop to a specific component that the component will receive false checked prop from this.props
.
But, if you wanna a have a prop on your specific component with a condition and if the condition returns false you don't want it there are two ways, I like second:
First:
<Component someProp={condition ? yourValue : undefined} />
Second:
<Component {...(condition && { someProp: yourValue })} />
In JSX, component properties (or props) compile to a plain JavaScript object. Prop names are used as the keys of the object, and prop values are stored under those keys. The first example from the JSX docs does a great good job demonstrating this. In your case {view === 'default' && true}
is a raw value without an associated prop name. Without a prop name to use as a key (specified by the syntax name=
), JSX has nowhere to put that value in the final props object.
However, JSX will accept props via your original syntax if the expression inside the curly braces evaluates to an object. For example, you could do {{ active: view === "default" }}
. In this case JSX can get both the key and value that it needs from the provided object, so no active=
is necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With