Here’s how to get stuff with JavaScript.
This is basic, but Boolean logic can handle two values: true and false,
or... potato or not potato. Then you can do stuff with it:
import DefaultIcon from './icons/Default'
import SpecialIcon from './icons/Special'
const hasDefaultIcon = true
const Icon = hasDefaultIcon ? DefaultIcon : SpecialIconBut what if the value can be more than two things? This post is about that.
The demo code
Let’s say we get an array from an API: ['club', 'diamond', 'heart', 'spade'],
and our task is to render playing cards, like so:
Let’s make a helper function called getSuit that gets us the right icon, which
in this case is
an SVG wrapped to a React component.
The above cards were rendered by the following code (getter highlighted):
<CardWrap>
{suits.map(suit => {
const Icon = getSuit(suit)
return (
<PlayingCard>
<Icon width={30} />
</PlayingCard>
)
})}
</CardWrap>Loads of if else statements
One way of implementing the icon getter helper is with a chain of if else
conditions:
const getSuit = suit => {
if (suit === 'club') {
return ClubsIcon
} else if (suit === 'diamond') {
return DiamondsIcon
} else if (suit === 'heart') {
return HeartsIcon
} else if (suit === 'spade') {
return SpadesIcon
} else {
return null
}
}That mess just doesn’t spark joy. I’ve completely stopped using the if else.
Loads of if statements
Somehow I find these if statements extremely simple and super readable:
const getSuit = suit => {
if (suit === 'club') return ClubsIcon
if (suit === 'diamond') return DiamondsIcon
if (suit === 'heart') return HeartsIcon
if (suit === 'spade') return SpadesIcon
return null
}There’s very little guesswork on how that works.
The switch case
Switch cases were basically made for this:
const getSuit = suit => {
switch (suit) {
case 'club':
return ClubsIcon
case 'diamond':
return DiamondsIcon
case 'heart':
return HeartsIcon
case 'spade':
return SpadesIcon
default:
return null
}
}Loads of keywords are flying around. There is no need for break in a case
when returning something.
Nested ternary condition
Nested ternaries work but are cryptic IMO:
const getSuit = suit => {
return suit === 'club'
? ClubsIcon
: suit === 'diamond'
? DiamondsIcon
: suit === 'heart'
? HeartsIcon
: suit === 'spade'
? SpadesIcon
: null
}Just an Object
Probably my favorite method of getting values is to just store them into an object, like so:
const suiteIcons = {
club: ClubsIcon,
diamond: DiamondsIcon,
heart: HeartsIcon,
spade: SpadesIcon,
}The object key is the name, as usual. Then access the object’s properties with bracket notation when you need them:
<CardWrap>
{suits.map(suit => {
const Icon = suiteIcons[suit] || null
return (
<PlayingCard>
<Icon width={30} />
</PlayingCard>
)
})}
</CardWrap>Note about the fallback: suiteIcons.potato is undefined, not null, and
React will crash if it’s not handled.
You can also do shenanigans like this, bake it all into one thing:
const Icon =
{
club: ClubsIcon,
diamond: DiamondsIcon,
heart: HeartsIcon,
spade: SpadesIcon,
}[suit] || nullConclusions
Maybe you had already used that object method without realizing it. I know I
had. It was nice to articulate this in a post. I also find myself becoming
disillusioned about else if.