Es6 वर्गों का उपयोग करते समय प्रतिक्रिया में "सुपर ()" और "सुपर (प्रॉप्स)" के बीच क्या अंतर है?


जवाबों:


709

जब कोई पास propsकरना हो तो केवल एक ही कारण है super():

जब आप this.propsकंस्ट्रक्टर में एक्सेस करना चाहते हैं ।

पासिंग:

class MyComponent extends React.Component {    
    constructor(props) {
        super(props)

        console.log(this.props)
        // -> { icon: 'home', … }
    }
}

नहीं गुजर रहा है:

class MyComponent extends React.Component {    
    constructor(props) {
        super()

        console.log(this.props)
        // -> undefined

        // Props parameter is still available
        console.log(props)
        // -> { icon: 'home', … }
    }

    render() {
        // No difference outside constructor
        console.log(this.props)
        // -> { icon: 'home', … }
    }
}

ध्यान दें कि गुजर या नहीं गुजर propsकरने के लिए superहै कोई प्रभाव के बाद के उपयोग के बारे में this.propsबाहर constructor। यही है render, shouldComponentUpdateया घटना संचालकों के पास हमेशा पहुंच होती है।

यह स्पष्ट रूप से एक सोफी अल्परट के समान प्रश्न के उत्तर में कहा गया है ।


प्रलेखन - राज्य और जीवनचक्र, स्थानीय राज्य को एक वर्ग में जोड़ते हुए , 2 बिंदु - बिंदु :

क्लास के घटकों को हमेशा बेस कंस्ट्रक्टर के साथ कॉल करना चाहिए props

हालांकि, कोई कारण नहीं दिया गया है। हम अनुमान लगा सकते हैं कि यह या तो उपवर्ग के कारण या भविष्य की अनुकूलता के लिए है।

(लिंक के लिए @MattBrowne को धन्यवाद)


16
मुझे लगता है कि आप सही हैं, अन्य उत्तरों के बावजूद अधिक वोट मिले। this.propsहै undefinedजब तक के लिए पारित किया super()। किसी भी तरह से, यह बाद में प्रतिपादन या की उपलब्धता को प्रभावित नहीं करता है this.propsमें render()कार्य करते हैं।
माइक्रो

3
@ रोरेटी, नहीं, वास्तव में बाकी वर्ग इस निर्माण पर निर्भर नहीं है, यही बात है। कंपोनेंट एक अलग तरीके से प्रॉपर प्राप्त करता है जो कि कंस्ट्रक्टर पैरामीटर द्वारा। और जब से आप प्रारंभिक प्रॉप्स पास करते हैं super, आपके पास कंस्ट्रक्टर में उनका संदर्भ होता है।
रोबिन पोकॉर्नी

7
प्रतिक्रिया प्रलेखन के अनुसार, आप हमेशा पास करना चाहिए propsकरने के लिए super(): facebook.github.io/react/docs/... । मुझे यकीन नहीं है कि, चूंकि आप इंगित करते हैं this.propsकि अन्य तरीकों में भी पहुंच योग्य है ... शायद वे भविष्य में अनुकूलता के लिए इसकी सिफारिश कर रहे हैं यदि रिएक्ट के भविष्य के संस्करण निर्माता के साथ कुछ करना चाहते हैं props?
मैट ब्राउन

23
हो सकता है कि मैं यहां सिर्फ एक कीड़ा खोल रहा हूं, लेकिन कभी भी क्यों पास करें , जैसा कि आपने बताया है, पैरामीटर हमारे लिए सही है कि हम कंस्ट्रक्टर के भीतर उपयोग करेंpropssuperprops , और this.propsहर जगह काम करता है? वहाँ का उपयोग करने के सभी पर एक फायदा है this.propsसिर्फ props? क्या propsकंस्ट्रक्टर में विनाश करना बुरा है ? मुझे लगता है कि मैं अभी भी एक मामले को देखने में विफल रहा हूं जब आपको कभी भी पास propsहोने की आवश्यकता होगी super, लेकिन मैं शर्त लगा सकता हूं कि यह सिर्फ मेरी अज्ञानता है, हा।
4

9
यदि आप उपयोग करते हैं super(props), तो आप उन तरीकों को कॉल कर सकते हैं , जो this.props निर्माता से उपयोग करते हैं , जैसे this.doStuffUsingThisDotProps(), उन विधियों / कार्यों के लिए प्रॉपर पैरामीटर पर पास किए बिना। मैंने सिर्फ एक निर्माणकर्ता को ऐसा करते हुए लिखा, जो super(props)इस प्रश्न के उत्तर के अनुसार प्रतीत होता है कि मुझे पहले उपयोग करना होगा ।
विक्टर ज़ामेनियन

54

इस उदाहरण में, आप React.Componentकक्षा का विस्तार कर रहे हैं , और ES2015 कल्पना के अनुसार, एक बच्चा वर्ग निर्माता thisतब तक उपयोग नहीं कर सकता है जब तक super()कि उसे बुलाया नहीं गया है; इसके अलावा, ES2015 क्लास कंस्ट्रक्टर्स को कॉल करना होगा super()यदि वे उपवर्ग हैं।

class MyComponent extends React.Component {
  constructor() {
    console.log(this); // Reference Error
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

इसके विपरीत:

class MyComponent extends React.Component {
  constructor() {
    super();
    console.log(this); // this logged to console
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

इस उत्कृष्ट स्टैक ओवरफ्लो उत्तर के अनुसार अधिक विस्तार

आप React.Componentकक्षा को बढ़ाते हुए बनाए गए घटकों के उदाहरण देख सकते हैं जो कॉल नहीं करते हैं super()लेकिन आप देखेंगे कि इनमें कोई आवश्यकता नहीं है constructor, इसलिए यह आवश्यक नहीं है।

class MyOtherComponent extends React.Component {
  render() {
    return <div>Hi {this.props.name}</div>;
  }
}

मेरे द्वारा बोले गए कुछ डेवलपर्स में से एक भ्रम की स्थिति यह है कि जिन घटकों की कोई संख्या नहीं है constructorऔर इसलिए वे super()कहीं भी कॉल नहीं करते हैं , फिर भी विधि this.propsमें उपलब्ध हैं render()। याद रखें कि यह नियम और इसके thisलिए constructorएकमात्र के लिए एक बंधन बनाने की आवश्यकता है constructor


15
आपके उत्तर के लिए बहुत बहुत धन्यवाद, लेकिन यह मेरे मूल प्रश्न (अंतर super()और super(props)) के बीच का उत्तर नहीं देता है ।
मीशा मोरशको

46

जब आप पास propsहोते हैं super, तो प्रॉप्स को सौंपा जाता है this। निम्नलिखित परिदृश्य पर एक नज़र डालें:

constructor(props) {
    super();
    console.log(this.props) //undefined
}

जब आप कैसे करते हैं:

constructor(props) {
    super(props);
    console.log(this.props) //props will get logged.
}

सूची में सबसे अच्छा जवाब।
बसवराज हदीमनी

यह उत्तर आधा सही है, यह उदाहरण केवल कंस्ट्रक्टर विधि के लिए है। उदाहरण के लिए, भले ही आप सुपर (प्रॉप्स) नहीं लिखते हैं, रेंडर विधि के तहत यह.प्रॉप्स अभी भी सौंपा और उपलब्ध होगा। ऊपर उल्लिखित एकमात्र कारण है जब कंस्ट्रक्टर में इस.प्रॉप्स का उपयोग करना।
Ofear

12

स्रोत कोड के अनुसार

function ReactComponent(props, context) {
  this.props = props;
  this.context = context;
}

propsजब भी आपके पास प्रॉप्स हों, आपको हर बार पास करना होगा और आप उन्हें this.propsमैन्युअल रूप से नहीं डालेंगे।


1
मैं अभी भी इस पर स्पष्ट नहीं हूं। यदि आप इन दो घटकों को देखते हैं, तो आप एक कॉल देख सकते हैं super(props)और दूसरा नहीं। लेकिन उनके उपभोक्ताओं ने दोनों को सहारा दिया। अंतर क्या है?
काइओटिक

क्या इसका मतलब यह है कि this.props = propsऔर super(props)एक ही चीज हैं?
रेक्ट्रिक्स

1
यह सच नहीं है। ReactElement वास्तव this.propsमें 'बाहरी' से सेट होता है-भले ही निर्माता में क्या किया गया हो।
रॉबिन पोकॉर्नी

11

दान अब्रामोव ने इस विषय पर एक लेख लिखा:

हम सुपर क्यों लिखते हैं (सहारा)?

और इसका सार यह है कि यह इस परिदृश्य से बचने के लिए इसे पारित करने की आदत रखने में मददगार है, ईमानदारी से, मुझे ऐसा होने की संभावना नहीं है:

// Inside React
class Component {
  constructor(props) {
    this.props = props;
    // ...
  }
}

// Inside your code
class Button extends React.Component {
  constructor(props) {
    super(); // 😬 We forgot to pass props
    console.log(props);      // ✅ {}
    console.log(this.props); // 😬 undefined 
  }
  // ...
}

8

super() पैरेंट कंस्ट्रक्टर को कॉल करने के लिए उपयोग किया जाता है।

super(props)propsपैरेंट कंस्ट्रक्टर को पास करेगा ।

आपके उदाहरण से, तर्क के रूप में गुजरने super(props)वाले React.Componentनिर्माता को कॉल करेगा props

अधिक जानकारी super: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super


18
हां, यही करता है। लेकिन क्यों ? और जब रिएक्ट में आवश्यक दो रूपों में से एक है?
बरगी

7

constructor()प्रतिक्रिया घटक के अंदर फ़ंक्शन को लागू करते समय , super()एक आवश्यकता होती है। ध्यान रखें कि आपका MyComponentघटक React.Componentबेस क्लास से कार्यक्षमता बढ़ा रहा है या उधार ले रहा है ।

इस बेस क्लास का अपना एक constructor()फंक्शन है, जिसके अंदर कुछ कोड है, जो हमारे लिए हमारे रिएक्ट कंपोनेंट को सेटअप करता है।

जब हम constructor()अपनी MyComponentकक्षा के अंदर एक फ़ंक्शन को परिभाषित करते हैं, तो हम अनिवार्य रूप से उस constructor()फ़ंक्शन को ओवरराइड या प्रतिस्थापित कर रहे हैं जो React.Componentकक्षा के अंदर है , लेकिन हमें अभी भी यह सुनिश्चित करने की आवश्यकता है कि इस constructor()फ़ंक्शन के अंदर सभी सेटअप कोड अभी भी कहलाते हैं।

तो सुनिश्चित करें कि React.Componentके constructor()समारोह में कहा जाता हो जाता है, तो हम कहते हैं super(props)super(props)माता-पिता के constructor()कार्य के लिए एक संदर्भ है , बस इतना ही है।

हमें super(props)हर एक समय को जोड़ना होता है जब हम constructor()एक क्लास-आधारित घटक के अंदर फ़ंक्शन को परिभाषित करते हैं।

यदि हम नहीं करते हैं तो हमें यह कहते हुए एक त्रुटि दिखाई देगी कि हमें कॉल करना है super(props)

इस constructor()funciton को परिभाषित करने का पूरा कारण हमारे राज्य वस्तु को इनिशियलाइज़ करना है।

तो हमारे राज्य वस्तु को इनिशियलाइज़ करने के लिए, मेरे द्वारा लिखी जा रही सुपर कॉल के नीचे:

class App extends React.Component {
  constructor(props) {
      super(props);

      this.state = {};
   }

  // React says we have to define render()
  render() {
    return <div>Hello world</div>;
  }
};

इसलिए हमने अपनी constructor()विधि को परिभाषित किया है , एक जावास्क्रिप्ट ऑब्जेक्ट बनाकर अपनी स्टेट ऑब्जेक्ट को इनिशियलाइज़ किया है, उसके लिए एक प्रॉपर्टी या की / वैल्यू पेयर असाइन करते हुए, उसी का परिणाम बताते हैं this.state। अब निश्चित रूप से यह सिर्फ एक उदाहरण है इसलिए मैंने वास्तव में एक महत्वपूर्ण / मूल्य जोड़ी को राज्य वस्तु को नहीं सौंपा है, यह सिर्फ एक खाली वस्तु है।


4

यहाँ मैंने जो फिडेल बनाया है वह है: jsfiddle.net । यह दर्शाता है कि प्रॉपर डिफ़ॉल्ट रूप से कंस्ट्रक्टर में नहीं दिए गए हैं। जैसा कि मैं समझता हूं कि वे विधि में गधे हैं React.createElement। इसलिए super(props)केवल तभी बुलाया जाना चाहिए जब सुपरक्लास का निर्माता मैन्युअल रूप से आश्वासन देता propsहै this.props। यदि आप सिर्फ React.Componentकॉल का विस्तार करते हैं super(props)तो प्रॉप्स के साथ कुछ नहीं करेंगे। हो सकता है कि इसे रिएक्ट के अगले संस्करणों में बदल दिया जाए।


3

यहां हमें यह कंस्ट्रक्टर में नहीं मिलेगा, इसलिए यह अपरिभाषित वापस आ जाएगा, लेकिन हम इसे कंस्ट्रक्टर फ़ंक्शन के बाहर लाने में सक्षम होंगे

class MyComponent extends React.Component {
  constructor() {
    console.log(this); // Reference Error i.e return undefined
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

यदि हम सुपर () का उपयोग कर रहे हैं, तो हम कंस्ट्रक्टर के अंदर "इस" चर को भी ला सकते हैं

class MyComponent extends React.Component {
  constructor() {
    super();
    console.log(this); // this logged to console
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

इसलिए जब हम सुपर () का उपयोग कर रहे हैं; हम इसे प्राप्त करने में सक्षम होंगे लेकिन यह। निर्माण में अपरिभाषित नहीं होगा। लेकिन कंस्ट्रक्टर के अलावा, यह। अप्रकाशित अपरिभाषित नहीं होगा।

यदि हम सुपर (प्रॉप्स) का उपयोग करते हैं, तो हम कंस्ट्रक्टर के अंदर भी इस। मान का उपयोग कर सकते हैं

सोफी अल्परट का जवाब

यदि आप कंस्ट्रक्टर में इस .प्रॉप्स का उपयोग करना चाहते हैं, तो आपको प्रॉपर से लेकर सुपर तक पास करना होगा। अन्यथा, इससे कोई फर्क नहीं पड़ता क्योंकि रिएक्टर सेट करता है। कंस्ट्रक्टर को कॉल करने के तुरंत बाद बाहर से उदाहरण देता है।


3

प्रतिक्रिया संस्करण 16.6.3 के लिए, हम राज्य तत्व नाम को इनिशियलाइज़ करने के लिए सुपर (प्रॉप्स) का उपयोग करते हैं : this.props.name

constructor(props){
    super(props);        
}
state = {
  name:this.props.name 
    //otherwise not defined
};
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.