ข้ามไปยังเนื้อหา

Props

ใน React props จะเข้ามาเป็น argument ตัวแรกของ component function แต่ใน Astro props จะเข้ามาผ่าน object ส่วนกลางชื่อ Astro.props ซึ่งคุณ destructure ออกมาใน frontmatter ด้วย syntax การ destructure แบบเดียวกับที่คุณรู้อยู่แล้ว

React
// Button.jsx
export default function Button({ label, variant = "primary" }) {
return (
<button className={`btn btn--${variant}`}>
{label}
</button>
);
}
// Usage:
// <Button label="Save" />
// <Button label="Delete" variant="danger" />
Astro
---
// Button.astro
const { label, variant = "primary" } = Astro.props;
---
<button class={`btn btn--${variant}`}>
{label}
</button>
<!-- Usage:
<Button label="Save" />
<Button label="Delete" variant="danger" />
-->

สองสิ่งที่ควรสังเกต:

  1. Astro.props คือตัวเทียบเท่าของ props object ใน React ให้ destructure ออกมาแบบเดียวกับที่คุณทำกับ parameter ของฟังก์ชัน
  2. ค่า default ทำงานด้วย default ของการ destructure ใน JavaScript มาตรฐาน (= "primary")

Astro component รองรับ TypeScript ในตัวอยู่แล้ว ประกาศ interface Props (หรือ type Props) ใน frontmatter แล้ว compiler จะบังคับใช้ type นั้นตอน build time

React
// Card.tsx
interface Props {
title: string;
description?: string;
href: string;
}
export default function Card({ title, description = "", href }: Props) {
return (
<a href={href} className="card">
<h2>{title}</h2>
{description && <p>{description}</p>}
</a>
);
}
Astro
---
// Card.astro
interface Props {
title: string;
description?: string;
href: string;
}
const { title, description = "", href } = Astro.props;
---
<a href={href} class="card">
<h2>{title}</h2>
{description && <p>{description}</p>}
</a>

การประกาศ interface Props คือ pattern แบบ idiomatic ของ Astro language server ของ Astro จะอ่าน type นี้เพื่อช่วยให้ editor autocomplete ได้ตอนที่คุณนำ component ไปใช้

Astro
---
interface Props {
  name: string;
  role?: string;
  color?: string;
}

const { name, role = "Developer", color = "#6366f1" } = Astro.props;
---
<html lang="en">
  <head><meta charset="utf-8" /><title>Props demo</title></head>
  <body style="font-family:sans-serif;padding:2rem">
    <div style={`border-left:4px solid ${color};padding-left:1rem`}>
      <h1>{name}</h1>
      <p style="color:#888">{role}</p>
    </div>
  </body>
</html>
คุณเข้าถึง props ภายใน frontmatter ของ Astro component ได้อย่างไร?
คุณกำหนดค่า default ให้ prop ที่เป็น optional ใน Astro ได้อย่างไร?
วิธีแบบ idiomatic ในการเพิ่ม TypeScript type ให้กับ props ของ Astro component คืออะไร?