جافا سكريبت - لماذا يتم استدعاء onClick عند التحميل؟ - React.js


لدي مكون قمت بإنشائه:

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);

عندما أقوم بعرض هذه الصفحة، يتم استدعاء activatePlaylist لكل playlist في map الخاص بي. إذا قمت بـ bind activatePlaylist مثل:

activatePlaylist.bind(this, playlist.playlist_id)

يمكنني أيضًا استخدام دالة مجهولة:

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

ثم يعمل كما هو متوقع. لماذا يحدث هذا؟

الإجابة رقم 1

تحتاج إلى تمرير reference إلى الدالة في onClick، عندما تفعل هكذا activatePlaylist( .. ) فإنك تستدعي الدالة وتمرر إلى onClick القيمة التي تم إرجاعها من activatePlaylist. يمكنك استخدام واحدة من هذه الخيارات الثلاثة:

1. استخدام .bind

activatePlaylist.bind(this, playlist.playlist_id)

2. استخدام دالة السهم

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

3. أو إرجاع دالة من activatePlaylist

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

الإجابة رقم 2

أعلم أن هذا المنشور قديم بالفعل بعدة سنوات، ولكن فقط للإشارة إلى أحدث درس/توثيق React بخصوص هذا الخطأ الشائع (لقد ارتكبته أنا أيضًا) من https://reactjs.org/tutorial/tutorial.html:

ملاحظة

لتوفير الكتابة وتجنب السلوك المربك لهذا، سوف نستخدم صياغة دالة السهم لمعالجات الأحداث هنا وفيما يلي:

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

لاحظ كيف مع onClick={() => alert('click')}، نحن نقوم بتمرير دالة كخاصية onClick. React ستستدعي هذه الدالة فقط بعد حدوث نقرة. نسيان() => وكتابة onClick={alert('click')} هو خطأ شائع، وسيؤدي إلى ظهور التنبيه في كل مرة يتم فيها إعادة عرض المكون.