React और TypeScript में children prop के पीछे क्या छिपा है?
\n\nअगर आपने कभी TypeScript के साथ React में कोई कम्पोनेंट लिखा है, तो आपने शायद यह सवाल पूछा होगा: "children prop का डेटा टाइप क्या है?"। यह सवाल Stack Overflow पर सबसे लोकप्रिय में से एक है, और यह कोई आश्चर्य की बात नहीं है। पहली नज़र में लगता है कि जवाब सरल है: ReactNode। लेकिन, जैसा कि कहा जाता है, असली मज़ा विवरणों में है।
इस लेख में हम सिर्फ एक सूखा जवाब नहीं देंगे। हम children के लिए सभी संभावित प्रकारों, उनके अंतरों, सर्वोत्तम अभ्यासों और संभावित समस्याओं पर गहराई से चर्चा करेंगे। आप जानेंगे कि कब ReactNode का उपयोग करना है, कब ReactElement का, और कब अधिक विशिष्ट प्रकारों का। चलिए शुरू करते हैं!
यह सवाल इतना लोकप्रिय क्यों है?
\n\nसमस्या यह है कि children React में एक विशेष prop है। यह कुछ भी हो सकता है:
- \n
- स्ट्रिंग:
"नमस्ते दुनिया!"\n - नंबर:
{42}\n - JSX एलिमेंट:
<div>...</div>\n - एलिमेंट्स की ऐरे:
[<span/>, <span/>]\n - फंक्शन (render prop):
{() => <div/>}\n - यहाँ तक कि
null,undefinedयाboolean\n
इस लचीलेपन के कारण, शुरुआती लोग अक्सर children: any लिख देते हैं, जो TypeScript के पूरे लाभ को खत्म कर देता है। आइए सही तरीकों को समझते हैं।
children के लिए मुख्य प्रकार
\n\n1. ReactNode — सबसे उपयोगी प्रकार
\n\nयह 90% मामलों में children के लिए सबसे सामान्य और सही प्रकार है। इसमें वह सब कुछ शामिल है जिसे React रेंडर कर सकता है।
import { ReactNode } from 'react';\n\ninterface CardProps {\n title: string;\n children: ReactNode;\n}\n\nfunction Card({ title, children }: CardProps) {\n return (\n <div className="card">\n <h2>{title}</h2>\n <div className="card-content">\n {children}\n </div>\n </div>\n );\n}\n\n// उपयोग:\n<Card title="मेरा कार्ड">\n <p>यह टेक्स्ट रेंडर होगा</p>\n {123} {/* नंबर भी काम करते हैं */}\n {null} {/* और null भी */}\n</Card>\n\nReactNode में क्या शामिल है? वास्तव में यह एक यूनियन है:
\n- \n
ReactElement— JSX एलिमेंट्स \n stringऔरnumber— प्रिमिटिव \n boolean,null,undefined— रेंडरिंग के दौरान अनदेखा किए जाते हैं \n ReactNode[]— उपरोक्त की ऐरे \n ReactPortal— पोर्टल्स \n
2. ReactElement — सख्त मोड
\n\nअगर आप चाहते हैं कि children केवल JSX एलिमेंट हो (स्ट्रिंग या नंबर नहीं), तो ReactElement का उपयोग करें।
import { ReactElement } from 'react';\n\ninterface StrictCardProps {\n children: ReactElement; // केवल एक JSX एलिमेंट\n}\n\nfunction StrictCard({ children }: StrictCardProps) {\n return <div className="strict-card">{children}</div>;\n}\n\n// काम करता है:\n<StrictCard><span>केवल एलिमेंट</span></StrictCard>\n\n// TypeScript त्रुटि:\n<StrictCard>टेक्स्ट</StrictCard> // ❌ स्ट्रिंग काम नहीं करेगी\n\nमहत्वपूर्ण: ReactElement को ठीक एक चाइल्ड एलिमेंट चाहिए। अगर आप बिना रैपर के दो एलिमेंट पास करते हैं, तो TypeScript त्रुटि देगा।
3. JSX.Element — ReactElement का उपनाम
\n\nटाइप JSX.Element वास्तव में ReactElement<any, any> है। यह ReactNode से कम लचीला है, और आमतौर पर children के लिए अनुशंसित नहीं है, जब तक कि आप कोई लाइब्रेरी नहीं लिख रहे हों।
// मूल रूप से, ये एक ही हैं:\ntype A = JSX.Element; // ReactElement<any, any>\ntype B = ReactElement; // Re