เจเนอริกของคอมโพเนนต์ — เบื้องต้น
สร้างคอมโพเนนต์ที่นำกลับมาใช้ใหม่ได้ด้วยพารามิเตอร์ชนิดข้อมูล ข้อจำกัด และการอนุมาน พร้อมส่งพร็อพสำหรับเรนเดอร์และคีย์ที่มีชนิดข้อมูลอย่างปลอดภัย
เจเนอริกของคอมโพเนนต์ — เบื้องต้น เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 3 บทเรียน
บทนำ
เป้าหมาย: ทำให้คอมโพเนนต์เดียวทำงานกับรูปร่างข้อมูลได้หลายแบบด้วย <T> คุณจะส่งพร็อพส์สำหรับการเรนเดอร์ที่มีชนิด จำกัดคีย์ และให้ TypeScript อนุมาน T จากการใช้งาน
- พร็อพส์ทั่วไปและฟังก์ชันเรนเดอร์
- ข้อจำกัดด้วย
extends - แยกคีย์โดยไม่ใช้ชนิดใดก็ได้
รายการทั่วไป<T>
List<T> แบบทั่วไปช่วยให้รายการและการเรนเดอร์สอดคล้องกัน ผู้ใช้สามารถส่ง T ใดก็ได้ และระบบจะอนุมานได้เมื่อเห็น T อย่างชัดเจน
import React from "react"
type ListProps<T> = { items: T[]; render: (item: T, index: number) => React.ReactNode }
export function List<T>({ items, render }: ListProps<T>) {
return <div style={{ display: "grid", gap: 6 }}>{items.map(render)}</div>
}
export default function App() {
return (
<div style={{ display: "grid", gap: 12 }}>
<List<number> items={[1,2,3]} render={(n) => <span>#{n}</span>} />
<List<{ id: string; name: string }>
items={[{ id: "u1", name: "Ada" }, { id: "u2", name: "Lin" }]}
render={(u) => <strong>{u.name}</strong>}
/>
</div>
)
}ข้อจำกัดด้วย extends
ใช้ T extends Keyed เพื่อกำหนดให้มี id สำหรับใช้เป็นคีย์ ผู้เรียกใช้จะได้รับข้อผิดพลาดหากส่งรายการที่ไม่มีฟิลด์ที่จำเป็น
import React from "react"
type Keyed = { id: string }
type KeyListProps<T extends Keyed> = { items: T[]; render: (item: T) => React.ReactNode }
export function KeyList<T extends Keyed>({ items, render }: KeyListProps<T>) {
return (
<ul>
{items.map((x) => (
<li key={x.id}>{render(x)}</li>
))}
</ul>
)
}
export default function App() {
const users = [{ id: "u1", name: "Ada" }, { id: "u2", name: "Lin" }]
return <KeyList items={users} render={(u) => <span>{u.name}</span>} />
}การอนุมาน T
โดยทั่วไป พารามิเตอร์ชนิดจะอนุมานจากพร็อพส์ ในที่นี้ T มาจาก items โปรดระบุชนิดเองเฉพาะเมื่อการอนุมานไม่ชัดเจน
import React from "react"
type GridProps<T> = { items: T[]; columns?: number; render: (item: T) => React.ReactNode }
export function Grid<T>({ items, columns = 2, render }: GridProps<T>) {
const css = { display: "grid", gridTemplateColumns: `repeat(${columns}, 1fr)`, gap: 8 }
return <div style={css as React.CSSProperties}>{items.map(render)}</div>
}
export default function App() {
const products = [
{ sku: "p1", title: "Mouse", price: 25 },
{ sku: "p2", title: "Keyboard", price: 80 }
]
// T is inferred from products; no need to annotate
return <Grid items={products} render={(p) => <span>{p.title} — ${p.price}</span>} />
}ตัวช่วยการเรนเดอร์
แยกชนิด Render<T> ที่นำกลับมาใช้ใหม่ได้เพื่อความชัดเจน หากจำเป็น ให้จำกัดด้วย (T extends { id: string }) เพื่อรองรับคีย์
import React from "react"
type Render<T> = (item: T) => React.ReactNode
type TableProps<T extends { id: string }> = { items: T[]; renderRow: Render<T> }
export function Table<T extends { id: string }>({ items, renderRow }: TableProps<T>) {
return (
<table>
<tbody>
{items.map((x) => (
<tr key={x.id}><td>{renderRow(x)}</td></tr>
))}
</tbody>
</table>
)
}
export default function App() {
const rows = [ { id: "1", label: "One" }, { id: "2", label: "Two" } ]
return <Table items={rows} renderRow={(r) => <span>{r.label}</span>} />
}แนวทางและข้อควรระวัง
แนวทาง:
- ควรเลือกใช้การอนุมาน และระบุชนิดเองเฉพาะเมื่อช่วยให้อ่านง่าย
- ใช้
extendsเพื่อแสดงข้อกำหนด - หลีกเลี่ยง
anyในพร็อพส์สำหรับการเรนเดอร์ทั่วไป เพราะทำให้ความปลอดภัยหมดไป
ตรวจสอบคอมโพเนนต์ทั่วไป
ตรวจสอบอย่างรวดเร็ว: การประกาศใดกำหนดคอมโพเนนต์ React แบบทั่วไปได้ถูกต้อง
สรุปทบทวน
สรุปทบทวน: ใช้ <T> เพื่อสร้างคอมโพเนนต์ที่นำกลับมาใช้ใหม่ได้ จำกัดด้วย extends สำหรับคีย์ และให้การอนุมานช่วยทำให้โค้ดกระชับ
คำถามที่พบบ่อย
บทเรียน “เจเนอริกของคอมโพเนนต์ — เบื้องต้น” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “เจเนอริกของคอมโพเนนต์ — เบื้องต้น” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 3 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “เจเนอริกของคอมโพเนนต์ — เบื้องต้น”
สร้างคอมโพเนนต์ที่นำกลับมาใช้ใหม่ได้ด้วยพารามิเตอร์ชนิดข้อมูล ข้อจำกัด และการอนุมาน พร้อมส่งพร็อพสำหรับเรนเดอร์และคีย์ที่มีชนิดข้อมูลอย่างปลอดภัย คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 3 บทเรียน
บทเรียน “เจเนอริกของคอมโพเนนต์ — เบื้องต้น” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม
ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พร็อพและลูก อีเวนต์แฮนด์เลอร์ และรีฟ
- สถานะและตัวลด; การกำหนดชนิดข้อมูล Context
- เจเนอริกของคอมโพเนนต์ — เบื้องต้น