2015-04-19 11 views
17

में इसका कोई कारण किसी कारण से प्रतिक्रिया ईवेंट हैंडलर में इसका मूल्य खो जा रहा है। डॉक्स मैंने सोचा था कि प्रतिक्रिया यहाँ कुछ सामान किया यकीन है कि यह सही मान के लिए स्थापित किया गया था बनाने के लिए पढ़नारिएक्ट इवेंट हैंडलर

निम्नलिखित के रूप में मैं

import React from 'react'; 

export default class Observer extends React.Component { 

    handleClick() { 
     console.log(this); //logs undefined 
    } 
    render() { 
     return (
      <button onClick={this.handleClick}>Click</button> 
     ); 
    } 
} 

उम्मीद थी काम नहीं करता है लेकिन यह करता है:

import React from 'react'; 

export default class Observer extends React.Component { 

    handleClick() { 
     console.log(this); //logs Observer class instance 
    } 
    render() { 
     return (
      <button onClick={this.handleClick.bind(this)}>Click</button> 
     ); 
    } 
} 

प्रतिक्रिया और ईएस 6 मेरे लिए नया है लेकिन यह सही व्यवहार नहीं लगता है?

+0

यह सही व्यवहार क्यों नहीं होगा? क्या jsx उस फ़ंक्शन को अस्पष्ट करता है जिसे आप 'ऑनक्लिक' के लिए बना रहे हैं? – Bergi

+0

इसका ईएस 6 के साथ कुछ लेना देना नहीं है। यह ईएस 5 में भी काम नहीं करेगा। – Bergi

+0

@ बर्गि स्वीकृत उत्तर अन्यथा कहता है। ईएस 5 में आप [React.createClass] (https://facebook.github.io/react/docs/top-level-api.html#react.createclass) का उपयोग करेंगे और आपको मैन्युअल रूप से बाध्य नहीं करना होगा। तो हाँ, प्रतिक्रिया घटक बनाने के लिए ES6 का उपयोग करके ओपी के साथ यह सबकुछ करना है। –

उत्तर

27

यह जावास्क्रिप्ट के लिए सही व्यवहार है और यदि आप नए class वाक्यविन्यास का उपयोग करते हैं तो प्रतिक्रिया दें।

autobinding feature does not apply to ES6 classes v0.13.0 में।

तो तुम का उपयोग करना होगा:

<button onClick={this.handleClick.bind(this)}>Click</button> 

या अन्य चाल में से एक:

export default class Observer extends React.Component { 
    constructor() { 
    super(); 
    this.handleClick = this.handleClick.bind(this); 
    } 
    handleClick() { 
    /* ... */ 
    } 
    render() { 
     return <button onClick={this.handleClick}>Click</button> 
    } 
} 
+0

ने स्पष्ट करने के लिए अपना उत्तर संपादित किया कि ऑटोबॉइडिंग प्रतिक्रिया के सभी संस्करणों में React.createClass के साथ काम करना जारी रखती है। स्पष्टीकरण बेन के लिए –

+0

धन्यवाद। – WiredPrairie

+1

ध्यान दें कि आपके द्वारा लिंक किए गए दस्तावेज़ों में तीर फ़ंक्शन हैंडलर बनाने के लिए ES7 क्लास गुणों का उपयोग करके एक और समाधान भी प्रदान करें, पूर्व 'हैंडलक्लिक = (ई) => {} ', फिर कन्स्ट्रक्टर या कहीं भी' बाइंड 'कॉल की आवश्यकता नहीं है। – Aaron

10

की तरह अन्य लोगों ने कहा, प्रतिक्रिया उदाहरण के लिए तरीकों जब ES6 का उपयोग कर autobind नहीं है कक्षाएं। जैसा कि कहा गया, मैं हमेशा की तरह ईवेंट हैंडलर्स में तीर फ़ंक्शन का उपयोग करने की आदत बनाना होगा: onClick={e => this.handleClick()}

के बजाय

: onClick={this.handleClick.bind(this)}

इसका कारण यह है इसका मतलब है कि आप handleClick विधि एक जासूस के साथ एक परीक्षण में, आप बदल सकते हैं कुछ जब आप बांध का उपयोग करते हैं तो नहीं कर सकते हैं।

+0

आपके तीर उदाहरण में, हैंडलक्लिक विधि को DOM तत्व को तर्क के रूप में नहीं मिलता है जब तक कि आप इसे स्पष्ट रूप से सही नहीं देते? –

+0

दाएं, इसे क्लिक करने वाले तत्व प्राप्त करने के लिए हैंडलक्लिक फ़ंक्शन के लिए 'onClick = {e => this.handleClick (e.target)} 'होना चाहिए। –

13

स्वीकार किए जाते हैं जवाब अच्छा है और मैं इसे ES6 में एक बहुत उपयोग किया है, लेकिन मैं सिर्फ एक और "अधिक आधुनिक" समाधान हम ES7 (React component class auto-binding notes में उल्लेख किया है) के साथ है जोड़ना चाहते हैं: class properties के रूप में तीर कार्यों का उपयोग, तो आपको कहीं भी अपने हैंडलर को बांधने या लपेटने की आवश्यकता नहीं है।

export default class Observer extends React.Component { 
    handleClick = (e) => { 
    /* ... */ 
    } 
    render() { 
     return <button onClick={this.handleClick}>Click</button> 
    } 
} 

यह अभी तक का सबसे सरल और साफ समाधान है!

+0

'onClick = {e => this.handle क्लिक नहीं है (ई)} 'अधिक प्रभावशाली? मेरा मानना ​​है कि यह लगभग 'this.handleClick = this.handleClick.bind (यह) 'जैसा ही है, सिवाय इसके कि बाद वाला डबल-टाइपिंग है। –

+2

मेरा उदाहरण '.bind()' का उपयोग नहीं करता है, यह वसा तीर को क्लास प्रॉपर्टी के रूप में परिभाषित करता है और इसे कॉलबैक प्रोप में बस पास करता है। मुझे लगता है कि यह कॉलबैक प्रोप के प्रत्येक प्रस्तुतिकरण में एक तीर फ़ंक्शन को परिभाषित करने से अधिक कुशल है, और कम टाइपिंग है, खासकर यदि आप अपने रेंडर फ़ंक्शन में एकाधिक स्थानों में हैंडलर का उपयोग करना चाहते हैं। – Aaron

संबंधित मुद्दे