คอมโพเนนต์แบบประกอบร่วมกับ Context
แชร์สถานะโดยนัยระหว่างคอมโพเนนต์แม่กับคอมโพเนนต์ลูกที่กำหนดไว้ โดยใช้ Context เพื่อสร้าง API อย่าง และ
คอมโพเนนต์แบบประกอบร่วมกับ Context เป็นบทเรียน Frontend Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Frontend Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน
คอมโพเนนต์ประกอบคืออะไร
คอมโพเนนต์ประกอบคือกลุ่มคอมโพเนนต์ที่เกี่ยวข้องกันและออกแบบมาให้ทำงานร่วมกันเป็นหน่วยเดียว เช่น <select> และ <option> ของ HTML คอมโพเนนต์แม่จะแชร์สถานะโดยนัยกับคอมโพเนนต์ลูกที่ระบุไว้
เป้าหมาย: อินเทอร์เฟซที่สะอาดขึ้น
แทนที่จะใช้ <Select options={[...]} value={x} onChange={...} /> คุณสามารถเขียน <Select><Option value="a">Apple</Option></Select> ได้ โครงสร้างนี้เป็นการประกาศและสอดคล้องกับ JSX โดยตรง
แนวทางแบบง่ายเกินไป (ปัญหา)
การส่งสถานะผ่านพร็อพส์ทำให้ผู้ใช้คอมโพเนนต์ต้องเชื่อมต่อทุกอย่างด้วยตนเอง คอมโพเนนต์ลูกจะไม่ทราบสถานะของคอมโพเนนต์แม่โดยอัตโนมัติ
// Without compound pattern — verbose:
<Tabs activeIndex={0} onChange={setIndex}>
<TabList>
<Tab index={0}>Home</Tab>
<Tab index={1}>Profile</Tab>
</TabList>
</Tabs>บริบทในฐานะตัวเชื่อมต่อ
คอมโพเนนต์แม่จะสร้างบริบทที่มีสถานะร่วมกันแล้วจัดเตรียมบริบทนั้นให้คอมโพเนนต์ลูก คอมโพเนนต์ลูกจะใช้บริบทโดยไม่ต้องเชื่อมต่อพร็อพส์อย่างชัดเจน
import { createContext, useContext, useState } from 'react';
const TabsContext = createContext(null);
export function Tabs({ children, defaultIndex = 0 }) {
const [activeIndex, setActiveIndex] = useState(defaultIndex);
return (
<TabsContext.Provider value={{ activeIndex, setActiveIndex }}>
<div className="tabs">{children}</div>
</TabsContext.Provider>
);
}คอมโพเนนต์ลูกใช้บริบท
คอมโพเนนต์ลูกแต่ละตัวอ่านค่าจากบริบท จึงไม่ต้องส่งพร็อพส์ลงมาตามลำดับชั้นของต้นไม้
export function Tab({ index, children }) {
const { activeIndex, setActiveIndex } = useContext(TabsContext);
const isActive = activeIndex === index;
return (
<button
className={isActive ? 'active' : ''}
onClick={() => setActiveIndex(index)}
>
{children}
</button>
);
}
export function Panel({ index, children }) {
const { activeIndex } = useContext(TabsContext);
if (activeIndex !== index) return null;
return <div className="panel">{children}</div>;
}พร็อพเพอร์ตีแบบคงที่เพื่อให้ค้นพบได้ง่าย
แนบคอมโพเนนต์ย่อยไว้กับคอมโพเนนต์แม่ เพื่อให้ผู้ใช้ค้นพบคอมโพเนนต์เหล่านั้นผ่านการเติมโค้ดอัตโนมัติ
Tabs.Tab = Tab;
Tabs.Panel = Panel;
// Usage:
<Tabs>
<Tabs.Tab index={0}>Home</Tabs.Tab>
<Tabs.Tab index={1}>Profile</Tabs.Tab>
<Tabs.Panel index={0}>Home content</Tabs.Panel>
<Tabs.Panel index={1}>Profile content</Tabs.Panel>
</Tabs>ตัวอย่างจริง: การเปิดเผย
วิดเจ็ตการเปิดเผยมีคอมโพเนนต์ลูกอย่าง Trigger และ Panel ซึ่งแชร์สถานะเปิดหรือปิดผ่านบริบท
function Disclosure({ children }) {
const [isOpen, setIsOpen] = useState(false);
return (
<DisclosureContext.Provider value={{ isOpen, setIsOpen }}>
<div>{children}</div>
</DisclosureContext.Provider>
);
}
function Trigger({ children }) {
const { isOpen, setIsOpen } = useContext(DisclosureContext);
return <button onClick={() => setIsOpen(o => !o)}>{children}</button>;
}
function Panel({ children }) {
const { isOpen } = useContext(DisclosureContext);
return isOpen ? <div>{children}</div> : null;
}ฮุกในฐานะอินเทอร์เฟซสาธารณะ
ส่งออกฮุกกำหนดเอง เพื่อให้ผู้ใช้สร้างคอมโพเนนต์ของตนเองต่อยอดจากคอมโพเนนต์ของคุณได้
export function useTabs() {
const ctx = useContext(TabsContext);
if (!ctx) throw new Error('useTabs must be used inside <Tabs>');
return ctx;
}คอมโพเนนต์ประกอบแบบพหุรูป
อนุญาตให้คอมโพเนนต์แม่แสดงผลเป็นองค์ประกอบใดก็ได้ผ่านพร็อพส์ as หรือรูปแบบ asChild ซึ่งเป็นแนวทางของ Radix UI วิธีนี้ทำให้คอมโพเนนต์ประกอบสามารถประกอบร่วมกับ JSX ใด ๆ ได้
รูปแบบคอมโพเนนต์ประกอบแบบไร้ส่วนแสดงผล
ไลบรารีแบบไร้ส่วนแสดงผล เช่น Radix และ Headless UI มีคอมโพเนนต์ประกอบที่ไม่มีการจัดรูปแบบ โดยฝังตรรกะด้านการเข้าถึงไว้ให้แล้ว และเปิดให้คุณจัดรูปแบบตามต้องการ
ข้อควรระวัง: การตรวจสอบคอมโพเนนต์ลูก
รูปแบบรุ่นเก่าใช้ React.Children เพื่อตรวจสอบคอมโพเนนต์ลูก ซึ่งเปราะบางและไม่ทนทาน ควรเลือกใช้บริบทเพื่อแชร์สถานะเสมอ
ตรวจสอบอย่างรวดเร็ว
ในรูปแบบคอมโพเนนต์ประกอบ คอมโพเนนต์ลูกสื่อสารกับคอมโพเนนต์แม่อย่างไร
ทบทวน: คอมโพเนนต์ประกอบ
คอมโพเนนต์ประกอบช่วยให้ส่วนที่เกี่ยวข้องกันทำงานเป็นหน่วยเดียวแบบประกาศ ใช้บริบทเพื่อแชร์สถานะ โดยให้ตัวให้บริการอยู่ในคอมโพเนนต์แม่และใช้ useContext ในคอมโพเนนต์ลูก แนบคอมโพเนนต์ย่อยเป็นพร็อพเพอร์ตีแบบคงที่เพื่อให้ค้นพบได้ง่าย ส่งออกฮุกกำหนดเองเป็นอินเทอร์เฟซสาธารณะ Radix และ Headless UI เป็นแหล่งอ้างอิงที่ดี และควรเลือกใช้บริบทแทนการตรวจสอบคอมโพเนนต์ลูก
คำถามที่พบบ่อย
บทเรียน “คอมโพเนนต์แบบประกอบร่วมกับ Context” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “คอมโพเนนต์แบบประกอบร่วมกับ Context” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Frontend Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “คอมโพเนนต์แบบประกอบร่วมกับ Context”
แชร์สถานะโดยนัยระหว่างคอมโพเนนต์แม่กับคอมโพเนนต์ลูกที่กำหนดไว้ โดยใช้ Context เพื่อสร้าง API อย่าง และ คุณปฏิบัติ Frontend Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Frontend Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Frontend Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “คอมโพเนนต์แบบประกอบร่วมกับ Context” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Frontend Academy นี้ได้ไหม
ได้ บทเรียน Frontend Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- คอมโพเนนต์แบบประกอบร่วมกับ Context
- พร็อพส์สำหรับเรนเดอร์และรูปแบบ HOC
- พอร์ทัลสำหรับโมดัลและทูลทิป
- ขอบเขตข้อผิดพลาด