iT邦幫忙

2024 iThome 鐵人賽

DAY 18
0
JavaScript

用 TypeScript 重新定義前端開發:30 天的實踐與思考系列 第 18

Day18:使用 TypeScript 為 React 元件定義 Props 型別

  • 分享至 

  • xImage
  •  

在 React 專案搭配 TypeScript 後續開發前,最重要的工作之一就是為元件定義 props 的型別。這不只可以讓程式碼更清晰易懂,也能幫助未來在開發過程中避免很多錯誤。今天的文章將以簡單明瞭的方式,介紹如何使用 TypeScript 來為 React 元件定義 props 型別,並提供一些實用的範例。

一、什麼是 Props?

Props 是 React 元件用來接收外部數據的機制。這些數據可以是從父元件傳遞過來的參數,類似於函數的參數。在 JavaScript 中,props 是動態的,你可以傳遞任何類型的數據;但在 TypeScript 中,我們可以為這些 props 定義具體的型別,以確保我們後續使用時傳入正確的數據。

二、為 React 元件定義 Props 型別

要為 React 元件定義 props 型別,通常會使用 TypeScript 的介面(interface)或型別別名(type)來描述 props 的結構。

1. 宣告一個使用介面(interface)元件的範例:

import React from 'react';

// 定義一個介面來描述 props 的型別
interface GreetingProps {
  name: string;
  age: number;
}

// 使用標準函數宣告來定義元件,並解構 props
function Greeting({ name, age }: GreetingProps) {
  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>You are {age} years old.</p>
    </div>
  );
};

export default Greeting;

在這個範例裡,我們使用了 interface 來定義 GreetingProps,描述元件 Greeting 會接收一個 name(型別為 string)和 age(型別為 number)。透過GreetingProps,我們告訴 TypeScript 這個元件會使用 GreetingProps 作為 props 的型別,這樣當我們使用該元件時,TypeScript 會檢查我們是否正確地傳遞了 nameage

2. 如何使用這個元件?

當我們在應用中使用這個元件時,TypeScript 會幫助我們確保我們傳入正確的 props。例如:

import React from 'react';
import Greeting from './Greeting';

function App() {
  return (
    <div className="App">
      {/* 正確的使用 */}
      <Greeting name="Annie" age={25} />

      {/* 錯誤的使用,TypeScript 會報錯 */}
      {/* <Greeting name="Billy" /> // 缺少 age 參數 */}
      {/* <Greeting name={101} age={25} /> // name 應為 string */}
    </div>
  );
}

export default App;

在上面的例子中,當我們正確地傳遞了 nameage,程式會順利執行;如果像上述程式碼區的段中的第11,12行忘記傳遞 age 或者傳遞了錯誤型別的 name(例如傳入 number),TypeScript 會在編譯時期給出提示,幫助我們及早發現並修正錯誤。

3. 使用型別別名(type)來定義 Props

除了使用介面,另一種方式是用型別別名(type)來定義 props 的型別。功能上與介面沒有太大差別,取決於個人的偏好。以下是使用型別別名的範例:

import React from 'react';

// 使用 type 來定義 props 型別
type ButtonProps = {
  label: string;
  onClick: () => void;
};

// 使用標準函數宣告來定義元件
function Button({ label, onClick }: ButtonProps) {
  return <button onClick={onClick}>{label}</button>;
};

export default Button;

這裡,我們定義了 ButtonProps,其中包含一個 label(型別為 string)和一個 onClick 函數(不返回任何值)。和介面類似,我們使用 ButtonProps 來告訴 TypeScript 我們這個元件的 props 是什麼型別。

三、選擇性 Props

當然,有時候我們可能不需要傳遞所有的 props。在這種情況下,就可以使用 TypeScript 提供的 ? 語法來定義選擇性 props。以下是一個搭配選擇性 props 的使用範例:

import React from 'react';

// 定義一個介面來描述 props 的型別
interface CardProps {
  title: string;
  description?: string; // description 是選擇性 props
}

// 使用標準函數宣告來定義元件
function Card({ title, description }: CardProps) {
  return (
    <div>
      <h2>{title}</h2>
      {description && <p>{description}</p>}
    </div>
  );
};

export default Card;

在這個範例中,description 是選擇性的。如果不傳入 description ,元件仍然會正常運行;而當 description 有值,它會顯示在畫面上,否則就不會顯示。

四、預設 Props 值

還有一種常見的情形,是可以給 props 設置預設值,這樣在沒有傳入某些 props 時,也能確保元件有合理的行為表現。例如:

import React from 'react';

// 定義一個介面來描述 props 的型別
interface AvatarProps {
  size?: number;
  username: string;
}

// 使用標準函數宣告來定義元件,並在參數中給定預設值
function Avatar({ size = 50, userId }: AvatarProps) {
  return 
    <img 
        src={`https://member.ithome.com.tw/avatars/${userId}`}
        alt={userId} 
        style={{
            width: `${size}px`,
            height: `${size}px`,
            borderRadius: '50%',
        }}
    />;
};

export default Avatar;

在這個範例中,如果沒有傳入 size,它會預設為 50px 的寬高預設值,這樣我們不必在每次使用元件時都手動設置大小。

五、結語

TypeScript 幫助我們在 React 開發中,為 props 定義明確的型別,確保傳遞的數據是正確的,從而提升程式碼的健壯性與可維護性。在這篇文章中,我分享了如何使用介面或型別別名來定義 props 型別,如何處理選擇性 props,以及如何設置預設值。這些技巧能夠都對 React 開發過程來說非常基本與實用,也可以讓應用程式從根本變得更加高效且安全。


上一篇
Day17:在 React 中使用 TypeScript 的基本設置與應用
下一篇
Day19:使用 TypeScript 處理 React 元件的 State 和 Context 型別
系列文
用 TypeScript 重新定義前端開發:30 天的實踐與思考30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言