Reputation: 7045
I'm trying to write something like this with a ternary operator (needed because of jsx syntax constraints)
if(!this.state.msg) {
if(this.state.ask.length != 0) {
// do stuff
} else {
// do stuff
}
if(this....) {
//do stuff
} else {
// ...
}
} else {
//nothing
}
So I tried this dumb
!this.state.msg ? this.state.ask.length != 0 ? //do stuff : "" this.state... ? //do stuff : //do other stuff : //nothing
But it's obviously not the right way to go.
Any help very welcomed. thanks in advance.
Upvotes: 5
Views: 6087
Reputation:
Your true branch has two components; you can separate them with commas (parenthesized, since the comma has weaker associativity than the ternary operator). So
!this.state.msg ?
(
this.state.ask.length != 0 ? /*stuff*/ : /*stuff*/,
this... ? /* stuff */ : /* ... */
) : /* nothing */
Or, since the else
branch is doing "nothing", you could replace the ternary operator at the top level with a simple and:
!this.state.msg &&
(
this.state.ask.length != 0 ? /*stuff*/ : /*stuff*/,
this... ? /* stuff */ : /* ... */
)
Upvotes: 5
Reputation: 29989
Maybe it'd help to add another perspective. It's very rare that you would actually need to use the ternary operator with JSX. In this case, I would consider moving all of this logic out into a separate function.
helperFunction: function() {
if(!this.state.msg) {
if(this.state.ask.length != 0) {
// return stuff
} else {
// return stuff
}
if(this....) {
// return stuff
} else {
// ...
}
} else {
// nothing
}
}
Then you'd be able to use your helper function from inside your render method.
React.createClass({
helperFunction: function() {
// ...
},
render: function() {
return (
<div>
{this.helperFunction()}
</div>
);
}
});
Your helper function can return values that can be used for attributes, or it can return other JSX components. Often I find it helpful to move code out of patterns that look like this:
render: function() {
return (
condition === 'example' ?
<MyComponent attr={this.props.example} onChange={this.props.onChange} /> :
<MyOtherComponent attr={this.state.example} onChange={this.state.onChange}/>
);
}
To code that looks like this:
helper: function(condition) {
if(condition === 'example') {
return (
<MyComponent attr={this.props.example} onChange={this.props.onChange} />
);
}
else {
return (
<MyOtherComponent attr={this.state.example} onChange={this.state.onChange}/>
);
}
},
render: function() {
return this.helper(condition);
}
Or even better in the case of string equality checking.
helper: function(condition) {
const default = <MyOtherComponent attr={this.state.example} onChange={this.state.onChange}/>
const conditions = {
example: <MyComponent attr={this.props.example} onChange={this.props.onChange} />,
example2: <MyComponent attr={this.props.example} onChange={this.props.onChange} />,
example3: <MyComponent attr={this.props.example} onChange={this.props.onChange} />,
};
return conditions[condition] || default;
},
render: function() {
return this.helper(condition);
}
This way gives you most of the power of a switch statement, but terser syntax too, it lets you elegantly select from a large number of conditional components. The same code written with if statements (regular or ternary) would be much more verbose.
Upvotes: 3
Reputation: 189
For verbosity, clarity of expression and maintainability, I would not recommend converting if-else to ternary expression. Try to keep your code simple even at the expense of few extra lines.
Here it is if you just want to learn
!this.state.msg ?
(this.state.ask.length != 0 ? //do if stuff : //do else stuff),
(this.some == 0 ? //do 2nd if stuff : //do 2nd else stuff)
:
Upvotes: 1
Reputation: 1878
You are wrong in your assertion that JSX limits you in this way - read this doc page and you will see that you can use something like this:
{(() => {
// My awesome multi-step code
})()}
Upvotes: 4
Reputation: 1670
Visualizing it helps.
!this.state.msg ?
? this.state.ask.length != 0)
// do stuff
:
// do stuff
:
this.... ?
//do stuff
:
// ...
Upvotes: 0