【译】在React中实现条件渲染的7种方法
原文地址:
借助react,我们可以构建动态且高度交互的单页应用程序,充分利用这种交互性的一种方法是通过条件渲染。
目录
条件渲染一词描述了根据某些条件渲染不同ui标签的能力。在react文档中,这是一种根据条件渲染不同元素或组件的方法。此概念通常被应用到如下情况中:
- 从api渲染外部数据
- 显示/隐藏元素
- 切换应用程序功能
- 实现权限级别
- 认证与授权
在本文中,我们将研究在react应用程序中实现条件渲染的7种方法。
挑战
首先,根据在组件state中isloggedin
的值,我们希望能够在用户未登入时显示login
按钮,在用户登入时显示logout
按钮。
下图是我们初始组件的截图:
代码如下:
import react, { component } from "react"; import reactdom from "react-dom"; import "./styles.css"; class app extends component { constructor(props) { super(props); this.state = { isloggedin: true }; } render() { return ( <div classname="app"> <h1> this is a demo showing several ways to implement conditional rendering in react. </h1> <button>login</button> <button>logout</button> </div> ); } } const rootelement = document.getelementbyid("root"); reactdom.render(<app />, rootelement);
在线测试:codesandbox
解决方法
在代码段中,…表示某些与所解释要点没有直接联系的代码。
1. 使用if…else语句
使用if…else
语句允许我们可以指出,如果条件为true
,则执行特定的操作,否则将执行其他操作。使用示例,我将测试if…else
通常用于在react中条件渲染的两种方法。
- 将条件渲染提取到函数中
在jsx中,我们可以将js代码和html标签放在一起,以确保程序内具有惊人的交互性。为此,我们使用大括号{}
并在其中编写我们的js。但在括号内能做事情也是有限的。例如,下面代码的结果并不能实现我们想要的结果。
// index.js ... render() { let {isloggedin} = this.state; return ( <div classname="app"> <h1> this is a demo showing several ways to implement conditional rendering in react. </h1> { if(isloggedin){ return <button>logout</button> } else{ return <button>login</button> } } </div> ); } ...
要了解更多相关信息,请访问此链接。
为了解决这个问题,我们将条件逻辑提取到一个函数中,如下所示:
// index.js ... render() { let {isloggedin} = this.state; const renderauthbutton = ()=>{ if(isloggedin){ return <button>logout</button> } else{ return <button>login</button> } } return ( <div classname="app"> <h1> this is a demo showing several ways to implement conditional rendering in react. </h1> {renderauthbutton()} </div> ); } ...
注意,我们将逻辑从jsx提取到函数renderauthbutton
中。因此,我们只需要在jsx大括号内执行函数即可。
- 多个返回语句
在使用此方法时,组件必须尽可能的简单,以避免兄弟或父组件的重新渲染。因此,我们创建了一个名为authbutton
的新组件。
// authbutton.js import react from "react"; const authbutton = props => { let { isloggedin } = props; if (isloggedin) { return <button>logout</button>; } else { return <button>login</button>; } }; export default authbutton;
authbutton
根据通过组件属性isloggedin
传入的状态值,返回不同的元素和组件。因此,我们将其导入index.js
并将状态值传入,如下所示:
// index.js ... import authbutton from "./authbutton"; ... render() { let { isloggedin } = this.state; return ( <div classname="app"> ... <authbutton isloggedin={isloggedin} /> </div> ); } ...
一定要避免下面的操作:
// index.js ... render() { let { isloggedin } = this.state; if (isloggedin) { return ( <div classname="app"> <h1> this is a demo showing several ways to implement conditional rendering in react. </h1> <button>logout</button>; </div> ); } else { return ( <div classname="app"> <h1> this is a demo showing several ways to implement conditional rendering in react. </h1> <button>login</button> </div> ); } } ...
虽然上述代码将实现相同的结果,但使得组件不必要的臃肿,同时由于不断重新渲染一个不变的组件而导致性能问题。
2. 使用元素变量
元素变量是上述的将条件渲染提取到函数中的一个扩展。元素变量只是保存jsx元素的变量。因此,我们可以在jsx外部根据条件将元素/组件赋值给这些变量,仅在jsx渲染变量即可。
// index.js ... render() { let { isloggedin } = this.state; let authbutton; if (isloggedin) { authbutton = <button>logout</button>; } else { authbutton = <button>login</button>; } return ( <div classname="app"> <h1> this is a demo showing several ways to implement conditional rendering in react. </h1> {authbutton} </div> ); } ...
注意我们如何有条件地将值(组件)分配给authbutton
,然后我们只需要在jsx中渲染它即可。
3. 使用switch语句
如前所示,我们可以使用if…else语句根据设置的条件从组件返回不同的标签。使用switch语句也可以达到相同的效果,在该语句中我们可以为不同的条件指定标签。看看如下代码:
// authbutton.js import react from "react"; const authbutton = props => { let { isloggedin } = props; switch (isloggedin) { case true: return <button>logout</button>; break; case false: return <button>login</button>; break; default: return null; } }; export default authbutton;
注意我们如何根据isloggedin
的值返回不同的按钮。当存在两个以上可能的值或结果时,采用此方法更为合理。你也可以通过break语句取消,正如return语句自动终止执行一样。
注意:从组件返回null
会使它隐藏自身/不显示任何内容。这是切换组件可见性的好方法。
4. 三元运算符
如果你熟悉三元运算符,那么你应该知道这是编写if语句的一种更简洁的方法。因此我们也许会这样写:
// index.js ... render() { let { isloggedin } = this.state; return ( <div classname="app"> <h1> this is a demo showing several ways to implement conditional rendering in react. </h1> {isloggedin ? <button>logout</button> : <button>login</button>} </div> ); } ...
但在上例中,这种方法会使组件臃肿,笨重和难以理解,你可以将条件封装在纯函数组件中。如下所示:
// authbutton.js import react from "react"; const authbutton = props => { let { isloggedin } = props; return isloggedin ? <button>logout</button> : <button>login</button>; }; export default authbutton;
5. 逻辑运算符&&
短路运算是一种用于确保在表达式运算过程中没有副作用的技术。逻辑&&帮助我们指定仅在一种情况下执行,否则将被完全忽略。这对于仅在特定条件为真时才需要执行的情况下是很有用的。
例如,如果是登录状态,我们只需显示logout
按钮,否则我们什么也不做。如下:
// index.js ... render() { let { isloggedin } = this.state; return ( <div classname="app"> <h1> this is a demo showing several ways to implement conditional rendering in react. </h1> {isloggedin && <button>logout</button>} </div> ); } ...
如果isloggedin
为true,则将显示logout
按钮,否则将不显示任何内容。我们用相同方法就可以实现最终结果,如下所示。
// index.js ... return ( <div classname="app"> <h1> this is a demo showing several ways to implement conditional rendering in react. </h1> {isloggedin && <button>logout</button>} {!isloggedin && <button>login</button>} </div> ); ...
这是基于isloggedin
的值渲染正确的按钮。但是,不建议这样做,因为有更好、更清洁的方法可以达到相同的效果。而且,一旦组件稍大一些,这很容易使你代码看起来混乱和难以理解。
6. 使用立即调用函数表达式(iife)
还记的刚才说的jsx局限性吗,在其中无法执行所有javascript代码。嗯...这并不完全正确的,因为有很多方法可以绕过这种行为。一种方法是使用iife。
(function () { statements })();
点击链接了解更多
通过这种技术,我们能够直接在jsx内编写条件逻辑,但将其包装在匿名函数中,该匿名函数在运行该部分代码后立即被调用。请参见下面的示例:
//index.js ... render() { let { isloggedin } = this.state; return ( <div classname="app"> <h1> this is a demo showing several ways to implement conditional rendering in react. </h1> {(function() { if (isloggedin) { return <button>logout</button>; } else { return <button>login</button>; } })()} </div> ); } ...
也可以使用箭头功能,通过更加简洁的方式编写该代码,如下所示:
// index.js ... return ( <div classname="app"> <h1> this is a demo showing several ways to implement conditional rendering in react. </h1> {(()=> { if (isloggedin) { return <button>logout</button>; } else { return <button>login</button>; } })()} </div> ); ...
7. 使用增强的jsx
某些库公开了扩展jsx的功能,因此可以直接用jsx实现条件渲染。此类库之一是jsx control statements。它是babel插件,可在编译过程中将类似组件的控制语句转换为javascript对应的语句。请参阅下面的示例以了解如何实现。
// index.js ... return ( <div classname="app"> <h1> this is a demo showing several ways to implement conditional rendering in react. </h1> <choose> <when condition={isloggedin}> <button>logout</button>; </when> <when condition={!isloggedin}> <button>login</button>; </when> </choose> </div> ); ...
但是,不建议使用这种方法,因为您编写的代码最终会转换为常规javascript条件。仅仅编写javascript可能总比对如此琐碎的事情增加额外的依赖要好。
性能问题
作为通用规则,最好确保在实现条件渲染时:
- 请勿随意更改组件的位置,以防止不必要地卸卸和重载组件。
- 仅更改与条件渲染有关的标签,而不改变组件中没有变动的部分。
- 不要在render方法中使组件不必要的臃肿,从而导致组件延迟渲染。
总结
我们已经成功研究了在react中实现条件渲染的7种方法。每种方法都有其自身的优势,选择哪种方法主要取决于实际情况。要考虑的事项包括:
- 条件渲染标签的大小
- 可能结果的数目
- 哪个会更直观和可读
通常,我建议:
- 当只有一个预期的结果时,使用逻辑&&运算符非常方便。
- 对于布尔型情况或只有两个可能结果的用例,可以使用if…else,element变量,三元运算符和iife。
- 如果结果超过2个,则可以使用switch语句,提取成函数或提取成纯函数组件。
但是,这些仅是建议,最终还是根据实际情况选择。
上一篇: JS 数组 常用方法
下一篇: react 报红错误汇总