前端框架

-

React 教學系列文 2 - JSX 的常用渲染方法,條件渲染、渲染列表

this.web

上篇文章 - React 教學系列文 1 - 學 React 一定要先理解的基礎重要概念

有了基礎的 React 觀念後,讓我們稍微講講一些常用渲染組建的方式。

  1. 條件渲染
  2. 列表渲染

React 條件渲染

有時候我們需要根據特定條件來決定渲染什麼樣的內容,例如當使用者是登入狀態時,顯示 “登入成功“;若使用者未登入,則顯示 "請登入” 和一個按鈕。

這時就需要使用條件渲染。

常用的條件渲染方式有

  1. if…else…
  2. 三元運算子
  3. &&、|| (And、Or) 邏輯

React 條件渲染 | if…else 語法

if…else… 是對初學者來說最直觀的寫法

import { useState } from 'react';

const LoginForm = () => {
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  if (isLoggedIn) {
    return (
      <>
        <div>登入成功!</div>
        <button onClick={() => setIsLoggedIn(false)}>登出</button>
      </>
    );
  } else {
    return (
      <>
        <div>請先登入</div>
        <button onClick={() => setIsLoggedIn(true)}>登入</button>
      </>
    );
  }
};

export default LoginForm;

這裡 if...else 根據 isLoggedIn 的值來決定渲染什麼內容。

如果 isLoggedIntrue,表示已登入則會渲染:

  • "登入成功!
  • 一個按鈕,點擊後會調用 setIsLoggedIn(false) 將登入狀態設置為 false (登出)

如果 isLoggedInfalse,表示未登入,則會渲染:

  • "請先登入"
  • 一個按鈕,點擊後會調用 setIsLoggedIn(true) 將登入狀態設置為 true (登入)

React 條件渲染 | 三元運算子

如果你不知道甚麼是三元運算子,這邊簡單說一下,它的語法是

(true or false) ? true 的話執行這裡 : false 執行這邊;

詳細的解釋可以參考 MDN

所以如果只是像上面這種簡單的條件判斷,我們更常使用三元運算子

import { useState } from 'react';

const LoginForm = () => {
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  return (
    <>
      {isLoggedIn ? ( // 👈 三元運算子
        <>
          <div>登入成功!</div>
          <button onClick={() => setIsLoggedIn(false)}>登出</button>
        </>
      ) : (
        <>
        <div>請先登入</div>
        <button onClick={() => setIsLoggedIn(true)}>登入</button>
      </>
      )}
    </>
  );
};

export default LoginForm;

記得前面說過,在 JSX 裡,只要使用 大括號 {} 就可以使用 JavaScript。

但要注意,過多使用三元運算子很容易讓程式碼變得難以理解,要斟酌使用。

React 條件渲染 | &&、|| (And、Or) 邏輯

在某些更簡單的條件渲染中,我們能直接使用 and & or 邏輯,這邊先簡單說一下 and & or。可以把 && 和 || 想像成一長條的鎖鏈,當前面的條件達成後,才會繼續往下看。

  • and (&&) : 如果左邊的條件為 true,則繼續右邊的操作 ; 如果左邊的條件為 false,則直接返回 false,不會去評估右邊的條件。
  • or (&&) : 如果左邊的條件為 true,則直接返回左邊的變數 ; 如果左邊的條件為 false,則繼續右邊的操作。

更詳細的解釋請參考 MDN

讓我們加入一個條件,判斷用戶是不是 VIP。並且顯示要不要充值成為 VIP 會員。

import { useState } from 'react';

const LoginForm = () => {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [isVIP, setIsVIP] = useState(false);

  return (
    <>
      {isLoggedIn ? (
        <>
          <div>登入成功!{isVIP && '嗨 VIP 會員!'}</div>
          {/* 若 isVIP 為 true,則顯示 "嗨 VIP 會員!" */}
          <button onClick={() => setIsLoggedIn(false)}>登出</button>
          {isVIP || (
            <button onClick={() => setIsVIP(true)}>成為 VIP 會員</button>
          )}
          {/* 若 isVIP 為 false,則顯示 "成為 VIP 會員" */}
        </>
      ) : (
        <>
          <div>請先登入</div>
          <button onClick={() => setIsLoggedIn(true)}>登入</button>
        </>
      )}
    </>
  );
};

export default LoginForm;

所以簡單說,用 && 時會返回最後一個為 true 的判斷式,若都為 false,則返回 false;用 || 會返回第一個為 true 的判斷式,若都為 false 則返回 false。

&&|| 也是在 React 中常用且簡潔的寫法。

React 列表渲染

在網站上,我們常常需要渲染大量的資料,例如多篇部落格貼文或多個使用者。這種大筆的資料通常都是用陣列儲存的,所以我們可以使用 JavaScript 陣列的 map 方法來處理和返回多筆資料。

先假設資料長這樣:

const posts = [
  { id: 1, title: '學習 React', content: '今天開始學習 React...' },
  { id: 2, title: '咖啡廳之旅', content: '城市新開了一座大咖啡廳...' },
  { id: 3, title: '看電影', content: '這個週末要和朋友看電影...' },
];

此時我們可以在 React 組件中這樣做

const Posts = () => {
  const posts = db.get('posts'); // 示意從 DataBase 取得資料
  return (
    <>
      {posts.map((post) => (
        <div>
          <h2>{post.title}</h2>
          <p>{post.content}</p>
        </div>
      ))}
    </>
  );
};

export default Posts;

React 列表渲染 | Key 值

由於 React 會自動幫我們操作返回的 DOM,為了讓 React 更有效率地做這件事,React 建議我們傳入一個 key 值給陣列裡的每個元素,例如

const Posts = () => {
  return (
    <>
      {posts.map((post) => (
        <div key={post.id}> 👈 加入 key 值
          <h2>{post.title}</h2>
          <p>{post.content}</p>
        </div>
      ))}
    </>
  );
};

在 React 中,建議所有的列表渲染都要添加 key 值,如果沒有加 key 值,React 也會在後台警告。

React 列表渲染 | 分解複雜的組件

我認為 React 其中一個強大之處,在於他讓組件化變得很直覺和容易,假設現在列表裡面很複雜,我們就可以提取出來,讓他變成子組件。

// src/SinglePost.jsx
const SinglePost = (post) => {
  return (
    <div key={post.id}>
      <h2>{post.title}</h2>
      <p>{post.content}</p>
    </div>
  )
}

// src/Posts.jsx
const posts = [
  { id: 1, title: '學習 React', content: '今天開始學習 React...' },
  { id: 2, title: '咖啡廳之旅', content: '城市新開了一座大咖啡廳...' },
  { id: 3, title: '看電影', content: '這個週末要和朋友看電影...' },
];
const Posts = () => {
  return (
    <>
      {/* 傳入 post 參數給 SinglePost */}
      {posts.map((post) => (
        <SinglePost post={post}/>
      ))}
    </>
  );
};

這樣去拆解組件,就能讓整個程式易於維護。

小結

今天說了條件渲染和列表渲染,這兩種渲染方式是 JSX 中最常見的應用。並且只要妥善拆分組件,就能做出架構清晰的應用,這是以往 JS 做不到的。

那今天就這樣,下篇貼文見~!

相關系列文章