मेरे onClick को रेंडर पर क्यों बुलाया जा रहा है? - React.js


100

मेरे पास एक घटक है जो मैंने बनाया है:

class Create extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    var playlistDOM = this.renderPlaylists(this.props.playlists);
    return (
      <div>
        {playlistDOM}
      </div>
    )
  }

  activatePlaylist(playlistId) {
    debugger;
  }

  renderPlaylists(playlists) {
    return playlists.map(playlist => {
      return <div key={playlist.playlist_id} onClick={this.activatePlaylist(playlist.playlist_id)}>{playlist.playlist_name}</div>
    });
  }
}

function mapStateToProps(state) {
  return {
    playlists: state.playlists
  }
}

export default connect(mapStateToProps)(Create);

जब मैं renderइस पृष्ठ, मेरे में activatePlaylistप्रत्येक के लिए कहा जाता है । अगर मुझे पसंद है:playlistmapbind activatePlaylist

activatePlaylist.bind(this, playlist.playlist_id)

मैं एक अनाम फ़ंक्शन का भी उपयोग कर सकता हूं:

onClick={() => this.activatePlaylist(playlist.playlist_id)}

फिर यह उम्मीद के मुताबिक काम करता है। क्यों होता है ऐसा?

जवाबों:


191

आपको फ़ंक्शन के onClick संदर्भ में पास की आवश्यकता होती है, जब आप ऐसा करते हैं तो activatePlaylist( .. )आप फ़ंक्शन को कॉल करते हैं और onClickउस मान को पास करते हैं जो से लौटा था activatePlaylist। आप इन तीन विकल्पों में से एक का उपयोग कर सकते हैं:

1 है । का उपयोग करते हुए.bind

activatePlaylist.bind(this, playlist.playlist_id)

। एरो फंक्शन का उपयोग करना

onClick={ () => this.activatePlaylist(playlist.playlist_id) }

। या वापसी समारोह सेactivatePlaylist

activatePlaylist(playlistId) {
  return function () {
     // you code 
  }
}

मुझे याद नहीं है कि यह Reactइस तरह से पिछले संस्करणों में काम करता है । क्या मुझे गलत याद है या apiबदल गया है?
झम्म

@ झाम आप ईएस 6 कक्षाओं का उपयोग कर रहे हैं और इस मामले में आपको संदर्भ को मैन्युअल रूप से बांधना चाहिए।
अलेक्जेंडर टी।

@AlexanderT। एक चीज है जो मुझे नहीं मिलती है। यदि आप संदर्भ को .bindचरण 1 में बांधते हैं, तो आपको चरण 2 करना आवश्यक है? और अगर ऐसा है, तो क्यों? क्योंकि मुझे लगता है कि जब आप एरो फ़ंक्शन का उपयोग करते हैं, तो संदर्भ वह होता है, जहां वह फ़ंक्शन परिभाषित होता है, लेकिन यदि हम उपयोग करते हुए संदर्भ संलग्न कर रहे हैं .bind, तो संदर्भ पहले से ही संलग्न है, है ना?
राफा रोमेरो

2
@ रफ़ा रोमेरो यह सिर्फ तीन अलग-अलग विकल्प हैं, आप उनमें से एक का उपयोग कर सकते हैं
अलेक्जेंडर टी।

2
अब आधिकारिक रिएक्ट डॉक्स वेबसाइट पर एक अनुभाग पूरी गहराई से इस सवाल का जवाब दिया है: reactjs.org/docs/faq-functions.html
zenoh

2

इस व्यवहार का दस्तावेजीकरण तब किया गया जब रिएक्ट ने कक्षा आधारित घटकों को जारी करने की घोषणा की।

https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html

Autobinding

React.createClass में एक अंतर्निहित मैजिक सुविधा है जो आपके लिए स्वचालित रूप से सभी विधियों को बाध्य करती है। यह जावास्क्रिप्ट डेवलपर्स के लिए थोड़ा भ्रमित हो सकता है जो अन्य वर्गों में इस सुविधा के लिए उपयोग नहीं किए जाते हैं, या जब वे प्रतिक्रिया से अन्य कक्षाओं में जाते हैं तो यह भ्रमित हो सकता है।

इसलिए हमने तय किया कि इस बिल्ट-इन रिएक्ट के क्लास मॉडल में नहीं। यदि आप चाहें तो आप अभी भी स्पष्ट रूप से अपने निर्माणकर्ता के तरीकों को पूर्व निर्धारित कर सकते हैं।


2

मुझे पता है कि यह पोस्ट कुछ साल पुरानी है, लेकिन इस सामान्य गलती के बारे में नवीनतम रिएक्ट ट्यूटोरियल / डॉक्यूमेंटेशन को संदर्भित करने के लिए (मैंने इसे भी बनाया है) https://reactjs.org/tutorial/tutorial.html से :

ध्यान दें

टाइपिंग को बचाने और इस के भ्रामक व्यवहार से बचने के लिए, हम यहां और आगे के हैंडलर के लिए एरो फ़ंक्शन सिंटैक्स का उपयोग करेंगे:

class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => alert('click')}>
       {this.props.value}
     </button>
   );
 }
}

ध्यान दें कि onClick = {() => अलर्ट ('क्लिक')} के साथ, हम onClick प्रोप के रूप में एक फ़ंक्शन पास कर रहे हैं। रिएक्ट केवल एक क्लिक के बाद इस फ़ंक्शन को कॉल करेगा। भूल जाना () => और onClick पर लिखना = {अलर्ट ('क्लिक')} एक सामान्य गलती है, और हर बार घटक फिर से रेंडर करने पर अलर्ट को आग लगा देगा।


1

जिस तरह से आप विधि पारित कर रहे हैं this.activatePlaylist(playlist.playlist_id) , तुरंत विधि को बुलाएगा। आपको onClickईवेंट के लिए विधि का संदर्भ पास करना चाहिए । अपनी समस्या को हल करने के लिए नीचे दिए गए कार्यान्वयन में से एक का पालन करें।

1।
onClick={this.activatePlaylist.bind(this,playlist.playlist_id)}

यहां बाइंड प्रॉपर्टी का इस्तेमाल पास करके this.activatePlaylistविधि का संदर्भ बनाने के लिए किया जाता हैthis संदर्भ और तर्कplaylist.playlist_id

2।
onClick={ (event) => { this.activatePlaylist.(playlist.playlist_id)}}

यह ऑनक्लिक ईवेंट पर एक फंक्शन अटैच करेगा जो केवल यूजर क्लिक एक्शन पर ट्रिगर हो जाएगा। जब यह कोड उम्मीद करता है कि this.activatePlaylistविधि को बुलाया जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.