I'd use an IIFE instead, so you can if/else.
{
(() => {
if (var1 && var2) return <Tag1 />;
if (error) return <Tag2 />;
return null;
})()
}
For the MyApp component, this simplifies to:
const MyApp = () => {
if (var1 && var2) return <Tag1 />;
if (error) return <Tag2 />;
return null;
};
Answer from CertainPerformance on Stack OverflowI'd use an IIFE instead, so you can if/else.
{
(() => {
if (var1 && var2) return <Tag1 />;
if (error) return <Tag2 />;
return null;
})()
}
For the MyApp component, this simplifies to:
const MyApp = () => {
if (var1 && var2) return <Tag1 />;
if (error) return <Tag2 />;
return null;
};
This is caused by the no-nested-ternaries eslint rule.
Linter rules are suggestions on how you should write your code, they point out best practices but not necessarily real "errors".
If it shows an "error" here, that is because someone (or a preconfigured ruleset) decided to enable this rule as "error level" for your project. Generally, there is no need to change your code unless you (or someone on your team) wants to forbid this style of coding. Technically, it is perfectly valid code and will work.
If you are on a team, talk with your team about the sense of that rule. If you are alone on your project, think if you want this rule or not and disable it in your .eslintrc file.
Personally I think that most suggestions on how to write this code instead given in other answers make it a lot less readable, so I'd keep it as this and disable the rule if I were you.
Yes, but my linter is not happy:
44:16 error Do not nest ternary expressions [no-nested-ternary]
If that's your only problem then the solution is simple. Create your own conditional function:
const iff = (condition, then, otherwise) => condition ? then : otherwise;
props => ({
iconColor: props.isPriority ?
iff(props.isCompleted, variables.color.lightpurple, variables.color.purple) :
variables.color.gray3,
iconName: props.isPriority ? 'star-full' : 'star-empty',
})
Now your linter shouldn't complain. That being said, you should disable [no-nested-ternary] in your linter. It's kind of stupid that your linter thinks that nested conditionals are bad.
I agree with @JaromandaX about using a function. That keeps your JSX clean and your logic reusable.
Apart from that, to avoid nested ternary operator, you can try something like this:
- Keep an array/map of all possible values
- Based on flags, create a binary string and convert it into number.
- return the value at provided index
function withTernary(a, b){
return a ? (b ? 'test': 'foo') : 'bar';
}
function withoutTernary(a, b){
var result = ['bar', undefined, 'foo', 'test'];
// or may be a map
/*
* map = {
* '00': 'bar',
* '10': 'foo',
* '11': 'test'
* }
*/
var index = parseInt((+a) + '' + (+b), 2);
return result[index];
}
var testCase = [[0,0], [1, 0], [1,1]];
testCase.forEach(x => {
console.log('With Ternary:', withTernary(...x));
console.log('Without Ternary:', withoutTernary(...x));
})
Your alternatives here are basically:
- That
if/elseyou don't want to do - A
switchcombined withif/else
I tried to come up with a reasonable lookup map option, but it got unreasonable fairly quickly.
I'd go for #1, it's not that big:
if (res.distance == 0) {
word = 'a';
} else if (res.distance == 1 && res.difference > 3) {
word = 'b';
} else if (res.distance == 2 && res.difference > 5 && String(res.key).length > 5) {
word = 'c';
} else {
word = 'd';
}
If all the braces and vertical size bother you, without them it's almost as concise as the conditional operator version:
if (res.distance == 0) word = 'a';
else if (res.distance == 1 && res.difference > 3) word = 'b';
else if (res.distance == 2 && res.difference > 5 && String(res.key).length > 5) word = 'c';
else word = 'd';
(I'm not advocating that, I never advocate leaving off braces or putting the statement following an if on the same line, but others have different style perspectives.)
#2 is, to my mind, more clunky but that's probably more a style comment than anything else:
word = 'd';
switch (res.distance) {
case 0:
word = 'a';
break;
case 1:
if (res.difference > 3) {
word = 'b';
}
break;
case 2:
if (res.difference > 5 && String(res.key).length > 5) {
word = 'c';
}
break;
}
And finally, and I am not advocating this, you can take advantage of the fact that JavaScript's switch is unusual in the B-syntax language family: The case statements can be expressions, and are matched against the switch value in source code order:
switch (true) {
case res.distance == 0:
word = 'a';
break;
case res.distance == 1 && res.difference > 3:
word = 'b';
break;
case res.distance == 2 && res.difference > 5 && String(res.key).length > 5:
word = 'c';
break;
default:
word = 'd';
break;
}
How ugly is that? :-)
To my taste, a carefully structured nested ternary beats all those messy ifs and switches:
const isFoo = res.distance === 0;
const isBar = res.distance === 1 && res.difference > 3;
const isBaz = res.distance === 2 && res.difference > 5 && String(res.key).length > 5;
const word =
isFoo ? 'a' :
isBar ? 'b' :
isBaz ? 'c' :
'd' ;
So I saw an article recently that was talking about minimizing the use of ternary operators where possible and reflecting on my own use of them especially in JSX, I have a few questions...
Before I get decided to post my questions, I checked React subs and most discussions on this are a couple years old at least and I thought perhaps views have changed.
Questions:
Is the main issue with using nested ternary operators readability?
I have found myself using ternary operators more and more lately and I even have my own way of formatting them to make them more readable. For example,
info.type === "playlist"
? info.creationDate
? <div className="lt-info-stats">
<span className="text pure">Created on {info.creationDate}</span>
</div>
: null
: info.type === "artist"
? <div className="lt-info-stats">
<span className="text pure">{info.genre}</span>
</div>
: <div className="lt-info-stats">
<span className="text pure">{info.releaseDate}</span>
<span className="cdot" style={{ fontWeight: "bold", margin: "1px" }}>·</span>
<span className="text pure">{info.genre}</span>
</div>When written like this, I can visually see the blocks and tell them apart and it looks a lot like how an if/else might look.
nested ternary operator formatting2. What is the preferred formatting of ternary operators in general and what do you think should be done to make them more readable?
3. How do people feel about nested ternary operators today? How big of a nono is it to have them in code (if it is a nono)?
I would love you know peoples thoughts on ternary operators in React in general as well.
Thanks for your attention!