React 条件渲染的 7 种最佳实践
这篇文章最初发表于https://www.devaradise.com/react-conditional-rendering-if-else
在 React 中,条件渲染可以通过多种方式实现,具体取决于上下文。在本文中,我们将讨论所有可用于在 React 中编写更好的条件渲染代码的方法。
~~
条件渲染是所有编程语言(包括 JavaScript)中都存在的一个常见功能。在 JavaScript 中,我们通常使用“if else”语句、“switch case”语句和三元运算符来编写条件渲染。
所有这些方法都适用于 React。但问题是,我们如何才能有效地使用它们?
你可能知道,React 有 JSX 标记,我们经常需要在其中为组件实现条件逻辑。但是,我们不能在 JSX 中直接使用常见的“if else”或“switch case”语句。
在 JSX 中,我们应该使用其他条件渲染方法,例如三元运算符和 && 运算符。本文我们将更详细地讨论这一点。
相关文章:
~~
在 React 中,我们至少可以使用 7 种条件渲染方法。每种方法在某些情况下都有其自身的优势。
目录
- 1. 使用 If Else 进行条件渲染
- 2. 使用三元运算符进行条件渲染
- 3. 使用短路 && 运算符进行条件渲染
- 4. 使用 Switch-Case 进行多条件渲染
- 5. 使用枚举对象进行多条件渲染
- 6. 使用 HOC 进行条件渲染
- 7. 使用外部库进行 JSX 条件渲染
1. 使用 If Else 进行条件渲染
最佳实践摘要
- 在 JSX 标记之外的任何地方使用
- 或者当你想在 if-else 块中执行多行代码时
~~
这是所有程序员都知道的第一个方法,即常见的 if-else 语句。我们可以在 React 项目的任何地方使用它。
在 React 中,当您想要在 if 或 else 块内或 JSX 外部的任何地方执行多行代码时,使用常见的 if-else 语句是最好的。
例如,如果用户登录,我们希望执行一些代码。
// * Conditional rendering with common if-else statement.
if(isLoggedIn) {
setUserProfile(userData);
setUserHistory(userHistory);
// other block of codes;
}
或者当您想根据用户角色定义可访问的内容时。
if(userProfile.role === 'superadmin') {
initSuperAdminFunction();
initSuperAdminComponent();
// other block of codes;
} else if(userProfile.role === 'admin') {
initAdminFunction();
initAdminComponent();
// other block of codes;
} else {
initUserComponent();
// other block of codes;
}
如果您只想执行一行代码,比如在 if 或 else 块内调用函数,您可以像这样删除括号。
if(userProfile.role === 'superadmin')
initSuperAdminComponent();
else if(userProfile.role === 'admin')
initAdminFunction();
else
initUserComponent();
if-else 中不带括号的条件仅适用于其正下方的一行代码。
JSX 中的 If else 语句
你可能知道,我们可以在 JSX 的括号 { } 内注入并混合一些 JavaScript 代码。但这有一些限制。
您不能直接在其中注入 if-else 语句。在 JSX 中注入 if-else 语句仅适用于立即调用函数表达式 (IIFE),如下所示:
return(
<div>
{
(() => {
if(isLoggedIn) {
return (<div>I'm logged in.</div>);
}
})()
}
</div>
)
如你所见,这对于一个 if 语句来说太冗长了。这就是为什么我不建议在 JSX 中使用 if-else 语句。
JSX 中还有一些其他的条件渲染方法,请继续阅读。
2. 使用三元运算符进行条件渲染
最佳实践摘要
- 使用它来为条件变量或函数返回值赋值
- 或者当你只想执行一行代码时
- 或者在 JSX 中进行条件渲染
~~
三元运算符是常用 if-else 语句的快捷方式。使用三元运算符,您可以内联编写条件渲染,或者仅用一行代码编写。
我们来看变量值赋值的条件渲染的例子。
// Conditional rendering with common if else
let isDrinkCoffee;
if(role === 'programmer') {
isDrinkCoffee = true;
} else {
isDrinkCoffee = false;
}
// Conditional rendering with ternary operator
let isDrinkCoffee = (role === 'programmer') ? true : false;
这是函数返回值的条件渲染示例:
// Conditional rendering with common if else
function isDrinkCoffee(role) {
if(role === 'programmer') {
return true;
} else {
return false;
}
}
// Conditional rendering with ternary operator
function isDrinkCoffee(role) {
return role === 'programmer' ? true : false;
}
如您所见,您可以使用三元运算符将 if-else 语句缩短为一行。
您还可以在 JSX 中使用三元运算符,而不是使用带有立即调用函数表达式 (IIFE) 的 if-else。
假设我们想要根据isShow
状态有条件地渲染一个小组件。你可以像这样编写条件渲染。
return (
<div>
{ isShow ? <SmallComponent/> : null }
</div>
)
if - else if - else 与三元运算符
在上面的例子中,我仅向您展示了如何使用三元运算符来替换 if-else 语句。
三元运算符还可以用来替代多重条件渲染(if - else if - else)或嵌套条件渲染。
但是,我不建议您使用它,因为它比常见的 if-else 语句更难阅读。
假设您想在 JSX 中实现嵌套条件渲染。
return (
<div>
{ condition_a
? <ComponentA/>
: ( condition_b
? <ComponentB/>
: ( condition_c
? <ComponentC/>
: <ComponentD/>
)
)
}
</div>
);
看起来很乱吧?
对于这种情况,使用 IIFE、switch-case 语句或枚举对象比三元运算符更好。
3. 使用短路 && 运算符进行条件渲染
最佳实践摘要
- 使用它进行简单的条件渲染,无需执行“else”块中的代码。
~~
使用三元运算符,您可以缩短 if-else 语句,并在 JSX 中进行条件渲染有更好的选择。
但是,您知道还有比三元运算符更简单的方法吗?
可以使用短路 AND 运算符来替换这样的 if 语句。
// Instead of using ternary operator,
{ isShow ? <SmallComponent/> : null }
// Use short-circuit && operator
{ isShow && <SmallComponent/> }
在三元运算符中,即使没有“else”条件,也应该继续写“:null”表达式以避免错误。
使用短路 && 运算符,您不必这样做。
但是,请记住,短路 && 运算符不能用于替代 if-else 语句,更不用说 if-else if-else 语句了。
4. 使用 Switch-Case 进行多条件渲染
最佳实践摘要
- 在任何地方使用它来进行只有一个变量来评估条件的多个条件渲染。
~~
与 if-else 语句一样,switch-case 语句也是几乎所有编程语言的共同特征。
用于同一类型条件的多重条件渲染。
例如,我们可以使用 switch-case 语句根据用户角色呈现特定的变量值。
let welcomeMessage;
switch(role) {
case 'superadmin':
welcomeMessage = 'Welcome Super Admin';
// you can put other codes here as well.
case 'admin':
welcomeMessage = 'Welcome Admin';
// you can put other codes here as well.
case 'user':
welcomeMessage = 'Welcome User';
// you can put other codes here as well.
default:
welcomeMessage = 'Welcome Guest';
// you can put other codes here as well.
}
你也可以在 JSX 中使用 switch-case 语句进行条件渲染。但是,你应该将其包装在 IIFE 中。
假设您想要渲染一个根据警报状态设置样式的警报组件。
return (
<div>
{
(() => {
switch(status) {
case 'warning':
return <AlertComponent status="warning" message={messageState}/>;
case 'error':
return <AlertComponent status="error" message={messageState}/>;
case 'success':
return <AlertComponent status="success" message={messageState}/>;
default:
return <AlertComponent status="info" message={messageState}/>;
}
})()
}
</div>
)
你可能已经注意到,这两个例子都只有一个变量(role
和status
)来评估条件。这就是我之前所说的同一类型的条件。
Switch-case 语句不适用于处理复杂且不同类型的条件。你应该使用常见的 if-else if-else 语句来处理这种情况。
5. 使用枚举对象进行多条件渲染
最佳实践摘要
- 仅当您想分配变量值或返回具有多个条件的值时才使用它。
~~
枚举对象也可用于在 React 中实现多条件渲染。它是 JSX 标记中 switch-case 语句的更好替代方案。
正如你之前在第五种方法中了解到的,你应该在 JSX 中将 switch-case 语句包裹在 IIFE 中。使用枚举对象时,你不需要这样做。
我们继续之前的例子。你想根据状态渲染一个 alert 组件。下面展示了如何使用枚举对象有条件地渲染它。
const ALERT_STATUS = {
warning: <AlertComponent status="warning"/>,
error: <AlertComponent status="error"/>,
success: <AlertComponent status="success"/>,
info: <AlertComponent status="info"/>
}
return (
<div>
{ ALERT_STATUS[status] }
</div>
)
如您所见,您需要首先创建一个名为“ALERT_STATUS”的枚举对象。然后,只需在 JSX 中使用status
括号内的变量调用它,该变量的值为“warning”、“error”、“success”或“info”。
如果<AlertComponent/>
需要传递其他的props或者属性,可以改成ALERT_STATUS
这样的函数。
const ALERT_STATUS = (message) => ({
warning: <AlertComponent status="warning" message={message}/>,
error: <AlertComponent status="error" message={message}/>,
success: <AlertComponent status="success" message={message}/>,
info: <AlertComponent status="info" message={message}/>
})
return (
<div>
{ ALERT_STATUS(messageState)[status] }
</div>
)
您还可以将警报组件分配给变量。
let newVariable = ALERT_STATUS(messageState)[status];
当然,你应该首先定义枚举对象。
将枚举对象分离为文件以使其可重复使用
使用枚举对象进行条件渲染的最大好处是可以重复使用。
回到示例,Alert 组件是 React 中通常可复用的组件。因此,当你需要有条件地渲染它时,也可以使其可复用。
您可以在单独的文件中定义枚举并像这样导出它。
import React from 'react';
import AlertComponent from './path/to/AlertComponent';
export const ALERT_STATUS = (message) => ({
warning: <AlertComponent status="warning" message={message}/>,
error: <AlertComponent status="error" message={message}/>,
success: <AlertComponent status="success" message={message}/>,
info: <AlertComponent status="info" message={message}/>
})
然后,当您想在组件中使用它时导入它。
import { ALERT_STATUS } from './alertStatus'
使用方法和以前一样。
6. 使用 HOC 进行条件渲染
最佳实践摘要
- 当您想要在渲染组件之前实现或检查某些条件时使用它。
~~
高阶组件 (HOC) 可用于在 React 中实现条件渲染。当你想在渲染组件之前运行某些逻辑或检查时,可以使用它。
例如,您想在用户访问某些组件之前检查用户是否已经过身份验证。
您无需在每个需要身份验证的组件中编写 if-else 语句,而是可以使用 HOC 来保护这些组件。
// This is Higher Order Component
import React from 'react'
export default function withAuthentication(Component) {
// some code of authentication logic/service that result an isLoggedIn variable/state:
let isLoggedIn = true;
return function AuthenticatedComponent(props) {
if(isLoggedIn) {
return <Component {...props}/>
} else {
return (<div class="alert alert-danger">You're not authenticated!</div>);
}
}
}
然后,您可以在组件中导入并使用它。
import withAuthentication from './withAuthentication'
const AuthenticatedUIComponent = withAuthentication(AnUIComponent);
return (
<div>
<AuthenticatedUIComponent/>
</div>
)
那样更好,对吧?
您可以将 HOC 用于其他可重复使用的条件渲染,如加载指示器实现、空检查等。
要了解有关 HOC(带有功能组件)的更多详细信息,您可以阅读 Medium 上的这篇文章。
7. 使用外部库进行 JSX 条件渲染
最佳实践摘要
- 避免使用此方法。熟悉以上 6 种方法 :D
~~
虽然我不建议您使用这种方法,但我只是想让您知道有一个 babel 插件可以使 JSX 拥有自己的条件渲染标签。
使用JSX 控制语句,您可以像这样在 JSX 中编写条件渲染。
<If condition={test}>
<span>Truth</span>
</If>;
<Choose>
<When condition={ test1 }>
<span>IfBlock</span>
</When>
<When condition={ test2 }>
<span>ElseIfBlock</span>
<span>Another ElseIfBlock</span>
<span>...</span>
</When>
<Otherwise>
<span>ElseBlock</span>
</Otherwise>
</Choose>
在编译中,这些标签将被转换为三元运算符。
一些开发人员使用此插件,因为它对于 JSX 中的条件渲染来说看起来更具可读性。
~~
这就是在 React 中可用于条件渲染的全部 7 种方法。
你知道 React 中其他条件渲染的方法吗?或者你对上述方法有什么想法?
请随意在下面的评论中提出建议!
编码愉快!
鏂囩珷鏉ユ簮锛�https://dev.to/syakirurahman/react-conditional-rendering-best-practices-with-7- Different-methods-16e3