javascript - प्रतिक्रियात्मक स्टेटलेस घटक, शुद्ध कॉम्पोनेंट, घटक; मतभेद क्या हैं और हमें कब उपयोग करना चाहिए?




1 Answers

आप कैसे निर्णय लेते हैं, आप इन तीनों के बीच अपने घटकों के उद्देश्य / आकार / प्रोप / व्यवहार के आधार पर कैसे चुनते हैं?

React.PureComponent या React.Component से एक कस्टम चाहिए shouldComponentUpdate विधि के प्रदर्शन प्रदर्शन प्रभाव है। स्टेटलेस कार्यात्मक घटकों का उपयोग करना एक "वास्तुशिल्प" विकल्प है और बॉक्स (अभी तक) से कोई प्रदर्शन लाभ नहीं है।

  • सरल, प्रस्तुति-केवल घटकों के लिए जिन्हें आसानी से पुन: उपयोग करने की आवश्यकता है, स्टेटलेस कार्यात्मक घटकों को प्राथमिकता दें। इस तरह आप सुनिश्चित हैं कि वे वास्तविक ऐप तर्क से decoupled हैं, कि वे परीक्षण करने के लिए मृत-आसान हैं और उनके पास अप्रत्याशित साइड इफेक्ट्स नहीं हैं। अपवाद यह है कि अगर किसी कारण से आपके पास बहुत सारे हैं या यदि आपको वास्तव में अपनी रेंडर विधि को अनुकूलित करने की आवश्यकता है (जैसा कि आप परिभाषित नहीं कर सकते हैं तो एक shouldComponentUpdate कार्यशील घटक के लिए shouldComponentUpdate )।

  • PureComponent यदि आप जानते हैं कि आपका आउटपुट सरल प्रोप / स्टेट पर निर्भर करता है ("सरल" जिसका मतलब कोई नेस्टेड डेटा संरचना नहीं है, क्योंकि शुद्ध कॉम्पोनेंट एक उथले तुलना करता है) और आपको कुछ प्रदर्शन सुधार / आवश्यकता हो सकती है।

  • Component विस्तारित करें और अपने स्वयं के shouldComponentUpdate यदि आपको अगले / वर्तमान प्रोप और राज्य के बीच कस्टम तुलना तर्क करके कुछ प्रदर्शन लाभ की आवश्यकता है। उदाहरण के लिए, आप lodash # isEqual का उपयोग करके गहरी तुलना कर सकते हैं:

    class MyComponent extends Component {
        shouldComponentUpdate (nextProps, nextState) {
            return !_.isEqual(this.props, nextProps) || !_.isEqual(this.state, nextState);
        }
    }
    

साथ ही, shouldComponentUpdate अपने स्वयं के shouldComponentUpdate या विस्तार को PureComponent करना अनुकूलन है, और सामान्य रूप से आपको केवल उसमें देखना शुरू करना चाहिए यदि आपके पास प्रदर्शन समस्याएं हैं ( समयपूर्व अनुकूलन से बचें )। अंगूठे के नियम के रूप में, एप्लिकेशन हमेशा काम करने वाले राज्य में होने के बाद इन अनुकूलन करने का प्रयास करता है, जिसमें पहले से ही लागू की गई अधिकांश सुविधाएं शामिल हैं। जब वे वास्तव में रास्ते में आते हैं तो प्रदर्शन समस्याओं पर ध्यान केंद्रित करना बहुत आसान होता है।

अधिक जानकारी

कार्यात्मक स्टेटलेस घटक:

इन्हें सिर्फ एक फ़ंक्शन का उपयोग करके परिभाषित किया जाता है। चूंकि एक स्टेटलेस घटक के लिए कोई आंतरिक स्थिति नहीं है, इसलिए आउटपुट (जो प्रस्तुत किया जाता है) केवल इस फ़ंक्शन में इनपुट के रूप में दिए गए प्रोपों पर निर्भर करता है।

पेशेवरों:

  • प्रतिक्रिया में एक घटक को परिभाषित करने का सबसे आसान तरीका। यदि आपको किसी भी राज्य को प्रबंधित करने की आवश्यकता नहीं है, तो कक्षाओं और विरासत से परेशान क्यों हो? फ़ंक्शन और कक्षा के बीच मुख्य अंतर यह है कि फ़ंक्शन के साथ आप सुनिश्चित हैं कि आउटपुट केवल इनपुट पर निर्भर करता है (पिछले निष्पादन के किसी भी इतिहास पर नहीं)।

  • आदर्श रूप से आपके ऐप में आपको लक्ष्य के रूप में कई स्टेटलेस घटकों का लक्ष्य रखना चाहिए, क्योंकि इसका सामान्य अर्थ यह है कि आपने व्यू परत के बाहर अपना तर्क स्थानांतरित कर दिया है और इसे रेडक्स जैसे कुछ स्थानांतरित कर दिया है, जिसका अर्थ है कि आप कुछ भी प्रस्तुत किए बिना अपने असली तर्क का परीक्षण कर सकते हैं (परीक्षण करने के लिए बहुत आसान है, अधिक पुन: प्रयोज्य, आदि)।

विपक्ष:

  • कोई जीवन चक्र तरीकों नहीं। आपके पास componentDidMount और अन्य मित्रों को परिभाषित करने का कोई तरीका नहीं है। आम तौर पर आप पदानुक्रम में एक मूल घटक के भीतर ऐसा करते हैं ताकि आप सभी बच्चों को स्टेटलेस में बदल सकें।

  • पुन: प्रस्तुत करने की आवश्यकता होने पर मैन्युअल रूप से नियंत्रित करने का कोई तरीका नहीं है, क्योंकि आप परिभाषित नहीं कर सकते हैं shouldComponentUpdate । एक बार फिर से प्रस्तुत होता है जब घटक को नए प्रोप प्राप्त होते हैं (उथले तुलना करने के लिए कोई रास्ता नहीं, इत्यादि)। भविष्य में, प्रतिक्रिया स्वचालित रूप से स्टेटलेस घटकों को अनुकूलित कर सकती है, क्योंकि अब कुछ पुस्तकालयों का उपयोग आप कर सकते हैं। चूंकि स्टेटलेस घटक केवल फ़ंक्शन हैं, मूल रूप से यह "फ़ंक्शन ज्ञापन" की क्लासिक समस्या है।

  • रेफ समर्थित नहीं हैं: https://github.com/facebook/react/issues/4936

एक घटक जो शुद्ध कॉम्पोनेंट क्लास वीएस को बढ़ाता है एक सामान्य घटक जो घटक वर्ग को बढ़ाता है:

एक PureRenderMixin लिए प्रयुक्त प्रतिक्रिया आप React.createClass वाक्यविन्यास का उपयोग करके परिभाषित कक्षा से संलग्न कर सकते हैं। shouldComponentUpdate बस एक shouldComponentUpdate को अगले प्रोप और अगले राज्य के बीच एक उथली तुलना करने के लिए परिभाषित करेगा, यह जांचने के लिए कि क्या कुछ भी बदल गया है या नहीं। यदि कुछ भी नहीं बदलता है, तो फिर से प्रस्तुत करने की कोई आवश्यकता नहीं है।

यदि आप ES6 वाक्यविन्यास का उपयोग करना चाहते हैं, तो आप mixins का उपयोग नहीं कर सकते हैं। तो सुविधा के लिए रिएक्ट ने एक PureComponent क्लास पेश किया PureComponent आप Component का उपयोग करने के बजाय प्राप्त कर सकते हैं। PureComponent बस लागू करना चाहिए shouldComponentUpdate के समान तरीके से PureRendererMixin । यह ज्यादातर सुविधा सुविधा है इसलिए आपको इसे स्वयं लागू करने की आवश्यकता नहीं है, क्योंकि वर्तमान / अगले राज्य और प्रोप के बीच एक उथली तुलना शायद सबसे आम परिदृश्य है जो आपको कुछ त्वरित प्रदर्शन जीत दे सकती है।

उदाहरण:

class UserAvatar extends Component {
    render() {
       return <div><img src={this.props.imageUrl} /> {{ this.props.username }} </div>
    }
} 

जैसा कि आप देख सकते हैं आउटपुट props.imageUrl और props.username पर निर्भर करता है। यदि एक मूल घटक में आप <UserAvatar username="fabio" imageUrl="http://foo.com/fabio.jpg" /> को उसी प्रोप के साथ render , तो प्रतिक्रिया प्रत्येक बार render लिए कॉल करेगी, भले ही आउटपुट बिल्कुल सही होगा वही। याद रखें कि प्रतिक्रिया डोम diffing लागू करता है, तो डीओएम वास्तव में अद्यतन नहीं किया जाएगा। फिर भी, डोम diffing प्रदर्शन महंगा हो सकता है, तो इस परिदृश्य में यह एक अपशिष्ट होगा।

यदि UserAvatar घटक इसके बजाय PureComponent बढ़ाता है, तो एक उथली तुलना की जाती है। और क्योंकि props और nextProps समान हैं, render करना बिल्कुल नहीं कहा जाएगा।

प्रतिक्रिया में "शुद्ध" की परिभाषा पर नोट्स:

आम तौर पर, एक "शुद्ध कार्य" एक ऐसा कार्य होता है जो एक ही इनपुट को उसी परिणाम के लिए हमेशा मूल्यांकन करता है। आउटपुट (प्रतिक्रिया के लिए, render विधि द्वारा जो किया जाता है) किसी भी इतिहास / राज्य पर निर्भर नहीं होता है और इसका कोई दुष्प्रभाव नहीं होता है (ऑपरेशन जो फ़ंक्शन के बाहर "दुनिया" को बदलता है)।

वास्तव में, उपरोक्त परिभाषा के अनुसार स्टेटलेस घटक जरूरी शुद्ध घटक नहीं हैं यदि आप "stateless" को एक घटक कहते हैं जो इसे कभी भी कॉल नहीं करता है this.setState और यह इसका उपयोग नहीं करता है। this.state

वास्तव में, एक PureComponent , आप अभी भी जीवन चक्र के तरीकों के दौरान दुष्प्रभाव प्रदर्शन कर सकते हैं। उदाहरण के लिए आप घटकडिडमाउंट के अंदर एक अजाक्स अनुरोध भेज सकते हैं या आप कुछ डीओएम गणना को गतिशील रूप से render भीतर एक div की ऊंचाई समायोजित करने के लिए कर सकते हैं।

"गूंगा घटक" परिभाषा में अधिक "व्यावहारिक" अर्थ होता है (कम से कम मेरी समझ में): एक गूंगा घटक "बताता है" प्रोप के माध्यम से एक मूल घटक द्वारा क्या करना है, और यह नहीं जानता कि चीजें कैसे करें लेकिन प्रोप का उपयोग करें इसके बजाय कॉलबैक।

एक "स्मार्ट" AvatarComponent का उदाहरण:

class AvatarComponent extends Component {
    expandAvatar () {
        this.setState({ loading: true });
        sendAjaxRequest(...).then(() => {
            this.setState({ loading: false });
        });
    }        

    render () {
        <div onClick={this.onExpandAvatar}>
            <img src={this.props.username} />
        </div>
    }
}

एक "गूंगा" AvatarComponent का उदाहरण:

class AvatarComponent extends Component {
    render () {
        <div onClick={this.props.onExpandAvatar}>
            {this.props.loading && <div className="spinner" />}
            <img src={this.props.username} />
        </div>
    }
}

अंत में मैं कहूंगा कि "गूंगा", "स्टेटलेस" और "शुद्ध" काफी अलग अवधारणाएं हैं जो कभी-कभी ओवरलैप कर सकती हैं, लेकिन जरूरी नहीं, ज्यादातर आपके उपयोग के मामले पर निर्भर करती हैं।

यह जानने के लिए कि React v15.3.0 से , हमारे पास PureRomponent नामक एक नई बेस क्लास है जिसे PureRenderMixin अंतर्निहित के साथ विस्तारित किया गया है। मैं समझता हूं कि, हुड के तहत यह shouldComponentUpdate अंदर shouldComponentUpdate की उथली तुलना को shouldComponentUpdate

अब हमारे पास एक प्रतिक्रिया घटक परिभाषित करने के 3 तरीके हैं:

  1. कार्यात्मक स्टेटलेस घटक जो किसी भी वर्ग का विस्तार नहीं करता है
  2. एक घटक जो PureComponent क्लास को बढ़ाता है
  3. एक सामान्य घटक जो Component वर्ग को बढ़ाता है

कुछ समय पहले हम शुद्ध घटक, या यहां तक ​​कि गूंगा घटक के रूप में स्टेटलेस घटकों को कॉल करते थे। ऐसा लगता है कि "शुद्ध" शब्द की पूरी परिभाषा अब प्रतिक्रिया में बदल गई है।

हालांकि मैं इन तीनों के बीच बुनियादी मतभेदों को समझता हूं, फिर भी मुझे यकीन नहीं है कि क्या चुनना है । प्रत्येक के प्रदर्शन प्रभाव और व्यापार-बंद क्या हैं?

अपडेट करें :

ये प्रश्न हैं जिन्हें मैं स्पष्ट करने की उम्मीद करता हूं:

  • क्या मुझे अपने सरल घटकों को कार्यात्मक (सादगी के लिए) के रूप में परिभाषित करना चाहिए या PureComponent क्लास (प्रदर्शन के लिए) का विस्तार करना PureComponent ?
  • क्या प्रदर्शन बढ़ता है कि मुझे खोने वाली सादगी के लिए एक वास्तविक व्यापार-बंद मिलता है?
  • क्या मुझे हमेशा सामान्य Component वर्ग का विस्तार करने की आवश्यकता होगी जब मैं हमेशा बेहतर प्रदर्शन के लिए PureComponent उपयोग कर सकता हूं?



Related