javascript - การใช้ React.Context เพื่อฉีด UI-Components เป็นความคิดที่ดีหรือไม่?
ฉันวางแผนที่จะสร้างไลบรารีคอมโพเนนต์ React คอมโพเนนต์ React เป็นคอมโพเนนต์ UI แต่ควรจะทำงานตามตรรกะเฉพาะเท่านั้น ฉันต้องการให้ผู้ใช้สามารถกำหนดชุดอะตอม (คอมโพเนนต์ React พื้นฐาน) ที่ใช้ประกอบคอมโพเนนต์จริง เป้าหมายหลักของฉันคือทำให้ไลบรารีไม่ขึ้นอยู่กับไลบรารีคอมโพเนนต์ UI เฉพาะ เช่น MaterialUI, ChakraUI เป็นต้น
ไอเดียของฉันคือการใช้ React.Context เพื่อฝังคอมโพเนนต์แบบนี้:
// Button Atom
const Button: FC = ({ children }) => (<button>{children}</button>)
const atoms = { button: Button }
const AtomContext = createContext(atoms);
// "higher" component
const HigherComponent: FC = () => {
const atoms = useContext(AtomContext)
// Logic ...
return (
<atoms.button>click me</atoms.button>
)
}
export default function App() {
return (
<AtomContext.Provider value={atoms}>
<HigherComponent />
</AtomContext.Provider>
);
}
นี่แก้ปัญหาของฉันได้ แต่ฉันไม่แน่ใจว่ามันเป็นไอเดียที่ดีหรือไม่ มีวิธีที่ดีกว่าในการฉีดขึ้นอยู่กับ UI หรือไม่ สิ่งใดอาจเป็นปัญหากับวิธีของฉัน?
คำตอบ #1
นี่คือคำถามที่สามารถให้คำตอบหลายแบบขึ้นอยู่กับประสบการณ์ส่วนบุคคล
แต่โดยรวมแล้วแนวคิดที่จะส่งผ่านคอมโพเนนต์ผ่านคอนเท็กซ์นั้นเป็นการใช้งานแนวคิดนั้นอย่างไม่ถูกต้องเล็กน้อย
นอกจากนี้มันยังไม่ได้นำประโยชน์มากมายจากการสร้างไลบรารีแบบสแตนด์อโลนที่สามารถนำเข้าได้ผ่าน package.json หรือการสร้างโฟลเดอร์ที่มีคอมโพเนนต์แล้วนำเข้ามาใช้งาน
หากคุณจำเป็นต้องส่งบางสิ่งบางอย่างไปยังคอมโพเนนต์ของคุณ คุณสามารถมีผู้ให้บริการแบบกำหนดเองได้ตามที่คุณทำไปแล้ว แต่สำหรับตัวคอมโพเนนต์เอง ไม่มีเหตุผลทั่วไปที่จะใช้ context
ถ้าจุดประสงค์สุดท้ายของคุณคือการย่อรายชื่อการนำเข้าของคอมโพเนนต์ด้วย custom context hook และเพียงแค่เรียกใช้มันแบบนั้น ผมคิดว่าโดยรวมแล้วมันเป็นการแลกเปลี่ยนที่ไม่ดี
คำตอบ #2
ฉันเพิ่งอ่านบทความเกี่ยวกับการใช้ React Context สำหรับการฉีดพึ่งพา ความคิดเห็นของผู้เขียนคือ การใช้ React Context สำหรับฉีดพึ่งพาที่ไม่ใช่ React เข้าไปในคอมโพเนนต์เป็นแนวทางที่ดี อย่างไรก็ตาม ฉันไม่แน่ใจว่าข้อนี้ใช้ได้กับการฉีดชุดคอมโพเนนต์ React ที่เฉพาะเจาะจงหรือไม่ เนื่องจากคอมโพเนนต์ React ไม่ต่างอะไรจากฟังก์ชัน ฉันคิดว่าควรจะใช้ React Context สำหรับสิ่งนั้นได้