React 条件渲染

ReactBeginner
立即练习

介绍

在 React 中,条件渲染是一个核心概念,它允许你根据特定条件或应用程序状态来显示不同的组件或元素。这对于构建动态和响应式的用户界面至关重要。例如,你可能希望向访客显示一个“登录”按钮,而向已登录用户显示“个人资料”页面。

在本实验中,你将学习几种在 React 应用中实现条件渲染的常用技术。我们将从一个基础的项目设置开始,并逐步探索不同的方法,包括:

  • 三元运算符 (? :) 用于简单的 if-else 逻辑。
  • 逻辑 && 运算符,仅在条件为真时渲染元素。
  • 使用变量存储元素,使 JSX 更简洁。
  • 返回 null 以阻止组件渲染。
  • 使用 React state 创建交互式 UI,以改变显示的内容。

在本实验结束时,你将对如何根据应用程序状态控制用户所见内容有扎实的理解。

在 JSX 中使用三元运算符进行条件判断

在本步骤中,你将学习如何在 JSX 中直接使用条件(三元)运算符 (? :) 来实现内联 if-else 逻辑。这是一种在渲染两个不同 UI 元素之间进行选择的简洁方式。

首先,让我们导航到我们的项目目录。所有命令都应从此目录运行。

cd ~/project/my-app

接下来,我们需要安装项目依赖。

npm install

现在,让我们修改主应用程序组件。在左侧的文件浏览器中打开文件 src/App.jsx。我们将创建一个 Greeting 组件,该组件根据用户是否登录显示不同的消息。

将 src/App.jsx 的全部内容替换为以下代码:

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  return (
    <div>{isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign up.</h1>}</div>
  );
}

function App() {
  return (
    <div>
      {/* 尝试将 isLoggedIn 改为 false,看看另一条消息! */}
      <Greeting isLoggedIn={true} />
    </div>
  );
}

export default App;

在 Greeting 组件中,表达式 {isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign up.</h1>} 检查 isLoggedIn prop 的值。如果为 true,则渲染“Welcome back!”。否则,渲染“Please sign up.”。

现在,让我们启动开发服务器,以便在实际中看到我们的组件。

npm run dev -- --host 0.0.0.0 --port 8080

服务器启动后,打开屏幕顶部的 Web 8080 标签页。你应该会看到“Welcome back!”消息。你可以尝试在 src/App.jsx 中将 isLoggedIn={true} 改为 isLoggedIn={false},保存文件,然后观察浏览器中内容的自动更新。

应用逻辑 && 运算符实现短路求值

在本步骤中,我们将探讨另一种常见的条件渲染模式:逻辑 && 运算符。当你只想在特定条件为真时渲染某个元素,否则渲染空内容时,它特别有用。在 JavaScript 中,true && expression 总是会评估为 expression,而 false && expression 总是会评估为 false。React 将 false 视为一个不渲染任何内容的“值”。

让我们修改 src/App.jsx 文件来演示这一点。我们将添加一个组件,该组件仅在有未读消息时显示通知计数。

保持开发服务器运行。你只需要编辑文件并保存它即可看到更改。

将 src/App.jsx 的内容替换为以下代码:

function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 && (
        <h2>You have {unreadMessages.length} unread messages.</h2>
      )}
    </div>
  );
}

function App() {
  const messages = ["React", "Re: React", "Re:Re: React"];
  // 尝试将 messages 改为空数组:const messages = [];
  return <Mailbox unreadMessages={messages} />;
}

export default App;

在此示例中,<h2> 元素之所以被渲染,仅仅是因为 unreadMessages.length > 0 为真。如果你在 App 组件中将 messages 数组变为空 (const messages = [];),条件将变为假,<h2> 元素将不会被渲染。

保存文件后,请检查 Web 8080 标签页。你应该会看到消息“You have 3 unread messages.”。

将条件存储在变量中并渲染为 true 时

在本步骤中,你将学习如何通过在 return 语句之前使用变量准备内容,来使你的组件更整洁。当条件逻辑比三元运算符或 && 运算符能优雅处理的更复杂时,这种方法非常有帮助。

通过使用变量,你可以使用标准的 JavaScript if 语句来决定组件应该渲染什么。

让我们更新 src/App.jsx 来使用这种技术。我们将创建一个组件,该组件根据一个 prop 显示“Login”或“Logout”按钮。

将 src/App.jsx 的内容替换为以下代码:

function LoginButton(props) {
  return <button>Login</button>;
}

function LogoutButton(props) {
  return <button>Logout</button>;
}

function LoginControl(props) {
  const isLoggedIn = props.isLoggedIn;
  let button;

  if (isLoggedIn) {
    button = <LogoutButton />;
  } else {
    button = <LoginButton />;
  }

  return (
    <div>
      The user is <b>{isLoggedIn ? "currently" : "not"}</b> logged in.
      {button}
    </div>
  );
}

function App() {
  return <LoginControl isLoggedIn={false} />;
}

export default App;

在 LoginControl 组件中,我们声明了一个变量 button。然后,一个 if 语句将 <LoginButton /> 或 <LogoutButton /> 赋值给它。最后,return 语句中的 JSX 只包含 {button}。这使得渲染逻辑分离,并使 return 语句更易于阅读。

保存文件并观察 Web 8080 标签页中的更改。你应该会看到“Login”按钮。尝试将 isLoggedIn={false} 改为 isLoggedIn={true},以查看“Logout”按钮。

条件为 false 时渲染 null 或空片段

在本步骤中,我们将介绍一种场景:你希望完全阻止某个组件渲染。你可以通过让该组件返回 null 或一个空片段(<> </>)来实现这一点。

这是一种常见模式,适用于那些只应在特定条件下可见的组件。例如,一个警告横幅,只有在实际存在警告时才应显示。

让我们修改 src/App.jsx 来包含一个 WarningBanner 组件,该组件仅在 warn prop 为 true 时渲染。

将 src/App.jsx 的内容替换为以下代码:

function WarningBanner(props) {
  if (!props.warn) {
    return null;
  }

  return (
    <div style={{ backgroundColor: "yellow", padding: "10px", color: "black" }}>
      Warning!
    </div>
  );
}

function App() {
  // 尝试将其更改为 false 以隐藏横幅
  const showWarning = true;

  return (
    <div>
      <WarningBanner warn={showWarning} />
      <p>This is the main content of the page.</p>
    </div>
  );
}

export default App;

在 WarningBanner 组件中,我们在开头检查 warn prop。如果它是 false,组件会立即返回 null,React 将不会为它渲染任何内容。如果它是 true,它将继续返回警告 div。

保存文件后,请检查 Web 8080 标签页。你将看到黄色的警告横幅。现在,返回 src/App.jsx,将 const showWarning = true; 更改为 const showWarning = false; 并保存。横幅将从页面上消失。

切换状态以更改条件显示

在最后这个步骤中,我们将条件渲染与 React 的 state 结合起来,创建一个交互式组件。到目前为止,我们的条件都基于 props。通过使用 state,我们可以让组件的输出响应用户的操作(例如点击按钮)而改变。

我们将使用 useState hook 来管理组件的 state。

让我们修改 src/App.jsx 来构建一个 LoginControl 组件,该组件管理自己的 isLoggedIn state,并允许用户切换它。

首先,你需要从 React 导入 useState。将 src/App.jsx 的内容替换为以下代码:

import { useState } from "react";

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <h1>Welcome back!</h1>;
  }
  return <h1>Please sign up.</h1>;
}

function LoginButton(props) {
  return <button onClick={props.onClick}>Login</button>;
}

function LogoutButton(props) {
  return <button onClick={props.onClick}>Logout</button>;
}

function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  const handleLoginClick = () => {
    setIsLoggedIn(true);
  };

  const handleLogoutClick = () => {
    setIsLoggedIn(false);
  };

  let button;
  if (isLoggedIn) {
    button = <LogoutButton onClick={handleLogoutClick} />;
  } else {
    button = <LoginButton onClick={handleLoginClick} />;
  }

  return (
    <div>
      <Greeting isLoggedIn={isLoggedIn} />
      {button}
    </div>
  );
}

export default App;

以下是代码的说明:

  1. import { useState } from 'react'; 引入了 useState hook。
  2. const [isLoggedIn, setIsLoggedIn] = useState(false); 初始化一个 state 变量 isLoggedIn 为 false。setIsLoggedIn 是我们用来更新此 state 的函数。
  3. 我们定义了 handleLoginClick 和 handleLogoutClick 函数,它们调用 setIsLoggedIn 来更新 state。
  4. LoginButton 和 LogoutButton 通过它们的 onClick prop 接收相应的处理函数。
  5. Greeting 组件和 button 变量都依赖于 isLoggedIn state,因此它们会在 state 更改时重新渲染。

保存文件并转到 Web 8080 标签页。你将看到“Please sign up.”消息和一个“Login”按钮。点击“Login”按钮。state 将更新,UI 将更改为显示“Welcome back!”和一个“Logout”按钮。

总结

恭喜你完成了关于 React 条件渲染的这个实验!你已经学习并实践了根据不同条件控制应用程序显示内容的最常用技术。

在这个实验中,你学习了:

  • 使用 三元运算符 (? :) 来实现简单的内联 if-else 逻辑。
  • 应用 逻辑 && 运算符 来仅在满足条件时渲染元素。
  • 将 JSX 存储在 变量 中,使用 if 语句处理更复杂的逻辑,保持 return 语句的整洁。
  • 从组件返回 null 以阻止其渲染任何内容。
  • 将这些技术与 useState hook 结合使用,创建动态且交互式的用户界面,以响应用户操作。

这些模式几乎是所有 React 应用程序的基础构建块。掌握它们将使你能够创建丰富、响应迅速且用户友好的体验。