आप कैसे तय करते हैं, आप हमारे घटकों के उद्देश्य / आकार / सहारा / व्यवहार के आधार पर इन तीनों के बीच कैसे चयन करते हैं?
कस्टम विधि के साथ React.PureComponent
या उससे विस्तार प्रदर्शन के निहितार्थ हैं। स्टेटलेस फंक्शनल कंपोनेंट्स का इस्तेमाल करना एक "आर्किटेक्चरल" विकल्प है और इसका कोई भी प्रदर्शन लाभ नहीं है।React.Component
shouldComponentUpdate
सरल, प्रेजेंटेशनल-केवल घटकों के लिए जिन्हें आसानी से पुन: उपयोग करने की आवश्यकता होती है, स्टेटलेस कार्यात्मक घटकों को प्राथमिकता देते हैं। इस तरह से आपको यकीन है कि उन्हें वास्तविक ऐप लॉजिक से अलग कर दिया जाता है, ताकि वे परीक्षण करने में आसान हों और उन पर अप्रत्याशित दुष्प्रभाव न पड़े। अपवाद अगर किसी कारण से आपके पास बहुत सारे हैं या यदि आपको वास्तव में उनकी रेंडर विधि को अनुकूलित करने की आवश्यकता है (जैसा कि आप shouldComponentUpdate
एक स्टेटलेस फंक्शनल कंपोनेंट के लिए परिभाषित नहीं कर सकते हैं)।
बढ़ाएँ PureComponent
यदि आप जानते हैं आपके उत्पादन सरल रंगमंच की सामग्री पर निर्भर करता है / राज्य ( "सरल" कोई नेस्टेड डेटा संरचनाओं तुलना अर्थ, PureComponent प्रदर्शन के रूप में एक उथले) और आप की जरूरत / कुछ प्रदर्शन में सुधार कर सकते हैं।
यदि आप अगले / वर्तमान सहारा और राज्य के बीच कस्टम तुलना तर्क प्रदर्शन करके कुछ प्रदर्शन लाभ की आवश्यकता है, तो Component
अपना खुद का विस्तार और कार्यान्वित करें shouldComponentUpdate
। उदाहरण के लिए, आप जल्दी से लॉश # isEqual का उपयोग करके एक गहरी तुलना कर सकते हैं:
class MyComponent extends Component {
shouldComponentUpdate (nextProps, nextState) {
return !_.isEqual(this.props, nextProps) || !_.isEqual(this.state, nextState);
}
}
इसके अलावा, अपने स्वयं के shouldComponentUpdate
या से लागू करने के PureComponent
अनुकूलन कर रहे हैं, और हमेशा की तरह आप उस पर गौर करना शुरू कर देना चाहिए यदि आपके पास प्रदर्शन के मुद्दे हैं ( समय से पहले अनुकूलन से बचें )। अंगूठे के एक नियम के रूप में, मैं हमेशा इन आशाओं को काम करने की स्थिति में करने की कोशिश करता हूं, जो कि पहले से ही लागू की गई अधिकांश विशेषताओं के साथ है। जब वे वास्तव में रास्ते में मिलते हैं तो प्रदर्शन समस्याओं पर ध्यान देना बहुत आसान होता है।
अधिक जानकारी
कार्यात्मक स्टेटलेस घटक:
इन्हें केवल एक फ़ंक्शन का उपयोग करके परिभाषित किया गया है। चूंकि एक स्टेटलेस घटक के लिए कोई आंतरिक स्थिति नहीं है, इसलिए आउटपुट (जो प्रदान किया गया है) केवल इस फ़ंक्शन के इनपुट के रूप में दिए गए प्रॉपर पर निर्भर करता है।
पेशेवरों:
प्रतिक्रिया में एक घटक को परिभाषित करने का सबसे सरल संभव तरीका। यदि आपको किसी राज्य का प्रबंधन करने की आवश्यकता नहीं है, तो कक्षाओं और विरासत के साथ परेशान क्यों हों? एक फ़ंक्शन और वर्ग के बीच मुख्य अंतर यह है कि फ़ंक्शन के साथ आप सुनिश्चित हैं कि आउटपुट केवल इनपुट पर निर्भर करता है (पिछले निष्पादन के किसी भी इतिहास पर नहीं)।
आदर्श रूप से आपके ऐप में आपको अधिक से अधिक स्टेटलेस घटक रखने का लक्ष्य होना चाहिए, क्योंकि सामान्य रूप से इसका मतलब है कि आपने अपने तर्क को व्यू लेयर से बाहर ले जाकर रेडक्स जैसी किसी चीज़ में स्थानांतरित कर दिया है, जिसका अर्थ है कि आप अपने असली तर्क का परीक्षण कर सकते हैं बिना कुछ भी प्रस्तुत किए। (परीक्षण के लिए बहुत आसान, अधिक पुन: प्रयोज्य, आदि)।
विपक्ष:
कोई जीवन पद्धति नहीं। आपके पास परिभाषित करने componentDidMount
और अन्य मित्रों के लिए कोई रास्ता नहीं है । आम तौर पर आप ऐसा करते हैं कि पदानुक्रम में उच्चतर मूल घटक के भीतर आप सभी बच्चों को स्टेटलेस में बदल सकते हैं।
जब आप परिभाषित नहीं कर सकते, तब से मैन्युअल रूप से नियंत्रण का कोई तरीका नहीं है, जब एक पुन: रेंडर करने की आवश्यकता होती है shouldComponentUpdate
। हर बार घटक नए प्रॉप्स (उथले तुलना, आदि के लिए कोई रास्ता नहीं) प्राप्त करता है। भविष्य में, प्रतिक्रिया स्वचालित रूप से स्टेटलेस घटकों को अनुकूलित कर सकती है, अब आपके लिए कुछ पुस्तकालयों का उपयोग किया जा सकता है। चूंकि स्टेटलेस घटक केवल कार्य हैं, मूल रूप से यह "फ़ंक्शन मेमोइज़ेशन" की क्लासिक समस्या है।
Refs समर्थित नहीं हैं: https://github.com/facebook/react/issues/4936
एक घटक जो PureComponent class VS को बढ़ाता है एक सामान्य घटक जो घटक वर्ग का विस्तार करता है:
PureRenderMixin
आप एक React.createClass
वाक्यविन्यास का उपयोग कर परिभाषित वर्ग के लिए संलग्न कर सकते थे करने के लिए इस्तेमाल किया प्रतिक्रिया । मिक्सचर बस shouldComponentUpdate
अगले प्रदर्शन और अगले राज्य के बीच एक उथले तुलना को परिभाषित करेगा कि क्या कुछ भी बदल गया है। यदि कुछ नहीं बदलता है, तो फिर से रेंडर करने की आवश्यकता नहीं है।
यदि आप ES6 सिंटैक्स का उपयोग करना चाहते हैं, तो आप मिश्रण का उपयोग नहीं कर सकते। इसलिए सुविधा के लिए रिएक्ट ने एक ऐसा 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
हर बार कॉल करेगा , भले ही आउटपुट बिल्कुल समान हो। हालांकि याद रखें कि रिएक्ट इम्प्रूवमेंट डोम में भिन्नता है, इसलिए DOM वास्तव में अपडेट नहीं किया जाएगा। फिर भी, डोम का प्रदर्शन करना महंगा हो सकता है, इसलिए इस परिदृश्य में यह एक बेकार होगा।
यदि UserAvatar
घटक PureComponent
इसके बजाय विस्तारित होता है , तो एक उथले तुलना की जाती है। और क्योंकि प्रॉप्स और नेक्स्टप्रॉप्स एक ही हैं, render
बिल्कुल भी नहीं कहा जाएगा।
प्रतिक्रिया में "शुद्ध" की परिभाषा पर नोट्स:
सामान्य तौर पर, "शुद्ध फ़ंक्शन" एक ऐसा फ़ंक्शन होता है जो समान इनपुट को दिए गए परिणाम के लिए हमेशा मूल्यांकन करता है। आउटपुट (रिएक्ट के लिए, जो कि render
विधि द्वारा लौटाया गया है ) किसी भी इतिहास / स्थिति पर निर्भर नहीं करता है और इसका कोई भी साइड-इफेक्ट नहीं है (ऑपरेशन जो "फ़ंक्शन के बाहर" दुनिया को बदलते हैं)।
प्रतिक्रिया में, स्टेटलेस घटकों को आवश्यक रूप से शुद्ध घटकों के अनुसार ऊपर परिभाषा के अनुसार नहीं कहा जाता है यदि आप "स्टेटलेस" एक घटक कहते हैं जो कभी कॉल नहीं करता है this.setState
और जो इसका उपयोग नहीं करता है this.state
।
वास्तव में, एक में PureComponent
, आप अभी भी जीवनचक्र विधियों के दौरान साइड-इफेक्ट कर सकते हैं। उदाहरण के लिए आप अंदर एक अजाक्स अनुरोध भेज componentDidMount
सकते हैं या आप कुछ डॉम गणना को गतिशील रूप से एक div की ऊंचाई को समायोजित करने के लिए कर सकते हैं render
।
"गूंगा घटकों" की परिभाषा का अधिक "व्यावहारिक" अर्थ है (कम से कम मेरी समझ में): एक गूंगा घटक "को बताया जाता है" एक मूल घटक के माध्यम से प्रॉप्स के माध्यम से क्या करना है, और चीजों को कैसे करना है पता नहीं है, लेकिन रंगमंच की सामग्री का उपयोग करता है इसके बजाय कॉलबैक।
"स्मार्ट" का उदाहरण AvatarComponent
:
class AvatarComponent extends Component {
expandAvatar () {
this.setState({ loading: true });
sendAjaxRequest(...).then(() => {
this.setState({ loading: false });
});
}
render () {
<div onClick={this.expandAvatar}>
<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>
}
}
अंत में मैं कहूंगा कि "गूंगा", "स्टेटलेस" और "शुद्ध" काफी अलग अवधारणाएं हैं जो कभी-कभी ओवरलैप कर सकती हैं, लेकिन जरूरी नहीं कि ज्यादातर आपके उपयोग के मामले पर निर्भर करें।