
A React komponens többféleképpen dönthet a megjelenítésről. Használhatja a hagyományos if
állítást vagy az switch
állítást. Ebben a cikkben néhány alternatívát vizsgálunk meg. Figyelmeztetni kell azonban, hogy egyesek saját gócával érkeznek, ha nem vigyázol.
Ternary vs if / else
Tegyük fel, hogy van egy komponensünk, amelyen átadunk egy name
támaszt. Ha a karakterlánc nem üres, akkor üdvözletet jelenítünk meg. Ellenkező esetben elmondjuk a felhasználónak, hogy be kell jelentkeznie.
Itt van egy hontalan funkciókomponens (SFC), amely éppen ezt teszi.
const MyComponent = ({ name }) => { if (name) { return ( Hello {name} ); } return ( Please sign in );};
Elég egyértelmű. De tehetünk jobban is. Itt van ugyanaz a komponens, amelyet egy feltételes hármas operátorral írtak .
const MyComponent = ({ name }) => ( {name ? `Hello ${name}` : 'Please sign in'} );
Vegye figyelembe, hogy ez a kód mennyire tömör a fenti példához képest.
Néhány megjegyzendő dolog. Mivel a nyílfüggvény egyetlen utasításformáját használjuk, az return
állítás implicit. Ezenkívül egy háromrészes használat lehetővé tette számunkra, hogy SZÁRAZZUK fel a másolatot
o"> markup. ?
Ternary vs Logical AND
As you can see, ternaries are wonderful for
if/else
conditions. But what about simple if
conditions?
Let’s look at another example. If
isPro
(a boolean) is true
, we are to display a trophy emoji. We are also to render the number of stars (if not zero). We could go about it like this.
const MyComponent = ({ name, isPro, stars}) => ( Hello {name} {isPro ? '?' : null} {stars ? ( Stars:{'⭐️'.repeat(stars)} ) : null} );
But notice the “else” conditions return
null
. This is becasue a ternary expects an else condition.
For simple
if
conditions, we could use something a little more fitting: the logical AND operator. Here’s the same code written using a logical AND.
const MyComponent = ({ name, isPro, stars}) => ( Hello {name} {isPro && '?'} {stars && ( Stars:{'⭐️'.repeat(stars)} )} );
Not too different, but notice how we eliminated the
: null
(i.e. else condition) at the end of each ternary. Everything should render just like it did before.
Hey! What gives with John? There is a
0
when nothing should be rendered. That’s the gotcha that I was referring to above. Here’s why.
According to MDN, a Logical AND (i.e.
&&
):
expr1 && expr2
Returns expr1
if it can be converted to false
; otherwise, returns expr2
. Thus, when used with Boolean values, &&
returns true
if both operands are true; otherwise, returns false
.OK, before you start pulling your hair out, let me break it down for you.
In our case, expr1
is the variable stars
, which has a value of 0
. Because zero is falsey, 0
is returned and rendered. See, that wasn’t too bad.
I would write this simply.
If expr1
is falsey, returns expr1
, else returns expr2
.So, when using a logical AND with non-boolean values, we must make the falsey value return something that React won’t render. Say, like a value of false
.
There are a few ways that we can accomplish this. Let’s try this instead.
{!!stars && ( {'⭐️'.repeat(stars)} )}
Notice the double bang operator (i.e. !!
) in front of stars
. (Well, actually there is no “double bang operator”. We’re just using the bang operator twice.)
The first bang operator will coerce the value of stars
into a boolean and then perform a NOT operation. If stars
is 0
, then !stars
will produce true
.
Then we perform a second NOT operation, so if stars
is 0, !!stars
would produce false
. Exactly what we want.
If you’re not a fan of !!
, you can also force a boolean like this (which I find a little wordy).
{Boolean(stars) && (
Or simply give a comparator that results in a boolean value (which some might say is even more semantic).
{stars > 0 && (
A word on strings
Empty string values suffer the same issue as numbers. But because a rendered empty string is invisible, it’s not a problem that you will likely have to deal with, or will even notice. However, if you are a perfectionist and don’t want an empty string on your DOM, you should take similar precautions as we did for numbers above.
Another solution
A possible solution, and one that scales to other variables in the future, would be to create a separate shouldRenderStars
variable. Then you are dealing with boolean values in your logical AND.
const shouldRenderStars = stars > 0;
return ( {shouldRenderStars && ( {'⭐️'.repeat(stars)} )} );
Then, if in the future, the business rule is that you also need to be logged in, own a dog, and drink light beer, you could change how shouldRenderStars
is computed, and what is returned would remain unchanged. You could also place this logic elsewhere where it’s testable and keep the rendering explicit.
const shouldRenderStars = stars > 0 && loggedIn && pet === 'dog' && beerPref === 'light`;
return ( {shouldRenderStars && ( {'⭐️'.repeat(stars)} )} );
Conclusion
I’m of the opinion that you should make best use of the language. And for JavaScript, this means using conditional ternary operators for if/else
conditions and logical AND operators for simple if
conditions.
While we could just retreat back to our safe comfy place where we use the ternary operator everywhere, you now possess the knowledge and power to go forth AND prosper.
I also write for the American Express Engineering Blog. Check out my other works and the works of my talented co-workers at AmericanExpress.io. You can also follow me on Twitter.