From 244a857e0f0f69d469a8ff6b1f96b6a6ca0f0a5e Mon Sep 17 00:00:00 2001 From: GraveAccent Date: Tue, 25 Sep 2018 23:25:55 +0800 Subject: [PATCH] =?UTF-8?q?GraveAccent=E7=BF=BB=E8=AF=91=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... Rendering in React using Ternaries and.md | 206 ------------------ ... Rendering in React using Ternaries and.md | 205 +++++++++++++++++ 2 files changed, 205 insertions(+), 206 deletions(-) delete mode 100644 sources/tech/20180201 Conditional Rendering in React using Ternaries and.md create mode 100644 translated/tech/20180201 Conditional Rendering in React using Ternaries and.md diff --git a/sources/tech/20180201 Conditional Rendering in React using Ternaries and.md b/sources/tech/20180201 Conditional Rendering in React using Ternaries and.md deleted file mode 100644 index b99c787e31..0000000000 --- a/sources/tech/20180201 Conditional Rendering in React using Ternaries and.md +++ /dev/null @@ -1,206 +0,0 @@ -GraveAccent 翻译中 Conditional Rendering in React using Ternaries and Logical AND -============================================================ - - -![](https://cdn-images-1.medium.com/max/2000/1*eASRJrCIVgsy5VbNMAzD9w.jpeg) -Photo by [Brendan Church][1] on [Unsplash][2] - -There are several ways that your React component can decide what to render. You can use the traditional `if` statement or the `switch` statement. In this article, we’ll explore a few alternatives. But be warned that some come with their own gotchas, if you’re not careful. - -### Ternary vs if/else - -Let’s say we have a component that is passed a `name` prop. If the string is non-empty, we display a greeting. Otherwise we tell the user they need to sign in. - -Here’s a Stateless Function Component (SFC) that does just that. - -``` -const MyComponent = ({ name }) => { - if (name) { - return ( -
- Hello {name} -
- ); - } - return ( -
- Please sign in -
- ); -}; -``` - -Pretty straightforward. But we can do better. Here’s the same component written using a conditional ternary operator. - -``` -const MyComponent = ({ name }) => ( -
- {name ? `Hello ${name}` : 'Please sign in'} -
-); -``` - -Notice how concise this code is compared to the example above. - -A few things to note. Because we are using the single statement form of the arrow function, the `return` statement is implied. Also, using a ternary allowed us to DRY up the duplicate `
` 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][3], 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. - --------------------------------------------------------------------------------- - -作者简介: - -Managing Editor at the American Express Engineering Blog http://aexp.io and Director of Engineering @AmericanExpress. MyViews !== ThoseOfMyEmployer. - ----------------- - -via: https://medium.freecodecamp.org/conditional-rendering-in-react-using-ternaries-and-logical-and-7807f53b6935 - -作者:[Donavon West][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://medium.freecodecamp.org/@donavon -[1]:https://unsplash.com/photos/pKeF6Tt3c08?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText -[2]:https://unsplash.com/search/photos/road-sign?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText -[3]:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators diff --git a/translated/tech/20180201 Conditional Rendering in React using Ternaries and.md b/translated/tech/20180201 Conditional Rendering in React using Ternaries and.md new file mode 100644 index 0000000000..aa7ba0017e --- /dev/null +++ b/translated/tech/20180201 Conditional Rendering in React using Ternaries and.md @@ -0,0 +1,205 @@ +在 React 条件渲染中使用三元表达式和 “&&” +============================================================ + +![](https://cdn-images-1.medium.com/max/2000/1*eASRJrCIVgsy5VbNMAzD9w.jpeg) +Photo by [Brendan Church][1] on [Unsplash][2] + +React 组件可以通过多种方式决定渲染内容。你可以使用传统的 if 语句或 switch 语句。在本文中,我们将探讨一些替代方案。但要注意,如果你不小心,有些方案会带来自己的陷阱。 + +### 三元表达式 vs if/else + +假设我们有一个组件被传进来一个 `name` prop。 如果这个字符串非空,我们会显示一个问候语。否则,我们会告诉用户他们需要登录。 + +这是一个只实现了如上功能的无状态函数式组件。 + +``` +const MyComponent = ({ name }) => { + if (name) { + return ( +
+ Hello {name} +
+ ); + } + return ( +
+ Please sign in +
+ ); +}; +``` + +这个很简单但是我们可以做得更好。这是使用三元运算符编写的相同组件。 + +``` +const MyComponent = ({ name }) => ( +
+ {name ? `Hello ${name}` : 'Please sign in'} +
+); +``` + +请注意这段代码与上面的例子相比是多么简洁。 + +有几点需要注意。因为我们使用了箭头函数的单语句形式,所以隐含了return语句。另外,使用三元运算符允许我们省略掉重复的 `
` 标记。🎉 + +### 三元表达式 vs && + +正如您所看到的,三元表达式用于表达 if/else 条件式非常好。但是对于简单的 if 条件式怎么样呢? + +让我们看另一个例子。如果 isPro(一个布尔值)为真,我们将显示一个奖杯表情符号。我们也要渲染星星的数量(如果不是0)。我们可以这样写。 + +``` +const MyComponent = ({ name, isPro, stars}) => ( +
+
+ Hello {name} + {isPro ? '🏆' : null} +
+ {stars ? ( +
+ Stars:{'⭐️'.repeat(stars)} +
+ ) : null} +
+); +``` + +请注意 “else” 条件返回 null 。 这是因为三元表达式要有"否则"条件。 + +对于简单的 “if” 条件式,我们可以使用更合适的东西:&& 运算符。这是使用 “&&” 编写的相同代码。 + +``` +const MyComponent = ({ name, isPro, stars}) => ( +
+
+ Hello {name} + {isPro && '🏆'} +
+ {stars && ( +
+ Stars:{'⭐️'.repeat(stars)} +
+ )} +
+); +``` + +没有太多区别,但是注意我们消除了每个三元表达式最后面的 `: null` (else 条件式)。一切都应该像以前一样渲染。 + + +嘿!约翰得到了什么?当什么都不应该渲染时,只有一个0。这就是我上面提到的陷阱。这里有解释为什么。 + +[根据 MDN][3],一个逻辑运算符“和”(也就是`&&`): + +> `expr1 && expr2` + +> 如果 `expr1` 可以被转换成 `false` ,返回 `expr1`;否则返回 `expr2`。 如此,当与布尔值一起使用时,如果两个操作数都是 true,`&&` 返回 `true` ;否则,返回 `false`。 + +好的,在你开始拔头发之前,让我为你解释它。 + +在我们这个例子里, `expr1` 是变量 `stars`,它的值是 `0`,因为0是 falsey 的值, `0` 会被返回和渲染。看,这还不算太坏。 + +我会简单地这么写。 + +> 如果 `expr1` 是 falsey,返回 `expr1` ,否则返回 `expr2` + +所以,当对非布尔值使用 “&&” 时,我们必须让 falsy 的值返回 React 无法渲染的东西,比如说,`false` 这个值。 + +我们可以通过几种方式实现这一目标。让我们试试吧。 + +``` +{!!stars && ( +
+ {'⭐️'.repeat(stars)} +
+)} +``` + +注意 `stars` 前的双感叹操作符( `!!`)(呃,其实没有双感叹操作符。我们只是用了感叹操作符两次)。 + +第一个感叹操作符会强迫 `stars` 的值变成布尔值并且进行一次“非”操作。如果 `stars` 是 `0` ,那么 `!stars` 会 是 `true`。 + +然后我们执行第二个`非`操作,所以如果 `stars` 是0,`!!stars` 会是 `false`。正好是我们想要的。 + +如果你不喜欢 `!!`,那么你也可以强制转换出一个布尔数比如这样(这种方式我觉得有点冗长)。 + +``` +{Boolean(stars) && ( +``` + +或者只是用比较符产生一个布尔值(有些人会说这样甚至更加语义化)。 + +``` +{stars > 0 && ( +``` + +#### 关于字符串 + +空字符串与数字有一样的毛病。但是因为渲染后的空字符串是不可见的,所以这不是那种你很可能会去处理的难题,甚至可能不会注意到它。然而,如果你是完美主义者并且不希望DOM上有空字符串,你应采取我们上面对数字采取的预防措施。 + +### 其它解决方案 + +一种可能的将来可扩展到其他变量的解决方案,是创建一个单独的 `shouldRenderStars` 变量。然后你用“&&”处理布尔值。 + +``` +const shouldRenderStars = stars > 0; +``` + +``` +return ( +
+ {shouldRenderStars && ( +
+ {'⭐️'.repeat(stars)} +
+ )} +
+); +``` + +之后,在将来,如果业务规则要求你还需要已登录,拥有一条狗以及喝淡啤酒,你可以改变 `shouldRenderStars` 的得出方式,而返回的内容保持不变。你还可以把这个逻辑放在其它可测试的地方,并且保持渲染明晰。 + +``` +const shouldRenderStars = + stars > 0 && loggedIn && pet === 'dog' && beerPref === 'light`; +``` + +``` +return ( +
+ {shouldRenderStars && ( +
+ {'⭐️'.repeat(stars)} +
+ )} +
+); +``` + +### 结论 + +我认为你应该充分利用这种语言。对于 JavaScript,这意味着为 `if/else` 条件式使用三元表达式,以及为 `if` 条件式使用 `&&` 操作符。 + +我们可以回到每处都使用三元运算符的舒适区,但你现在消化了这些知识和力量,可以继续前进 && 取得成功了。 + +-------------------------------------------------------------------------------- + +作者简介: + +美国运通工程博客的执行编辑 http://aexp.io 以及 @AmericanExpress 的工程总监。MyViews !== ThoseOfMyEmployer. + +---------------- + +via: https://medium.freecodecamp.org/conditional-rendering-in-react-using-ternaries-and-logical-and-7807f53b6935 + +作者:[Donavon West][a] +译者:[GraveAccent](https://github.com/GraveAccent) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://medium.freecodecamp.org/@donavon +[1]:https://unsplash.com/photos/pKeF6Tt3c08?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText +[2]:https://unsplash.com/search/photos/road-sign?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText +[3]:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators