렌더링시 내 onClick이 호출되는 이유는 무엇입니까? -React.js


101

내가 만든 구성 요소가 있습니다.

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

I되면 render이 페이지는 activatePlaylist각각라고 playlist않은 내 map. 내가 bind activatePlaylist좋아 한다면 :

activatePlaylist.bind(this, playlist.playlist_id)

익명 함수를 사용할 수도 있습니다.

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

그러면 예상대로 작동합니다. 왜 이런 일이 발생합니까?

답변:


197

함수 에 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 
  }
}

React이런 식으로 이전 버전에서 작동했던 기억이 없습니다 . 내가 잘못 기억하고 있거나 api변경 되었습니까?
jhamm

@jhamm ES6 클래스를 사용하고 있으며이 경우 컨텍스트를 수동으로 바인딩해야합니다.
Oleksandr T.

@AlexanderT. 내가 이해하지 못하는 한 가지가 있습니다. .bind1 단계에서 말했듯 이 컨텍스트를로 바인딩하면 2 단계를 수행해야합니까? 그렇다면 그 이유는 무엇입니까? 화살표 함수를 사용하면 컨텍스트가 함수가 정의 된 곳이라고 생각하기 때문에을 사용하여 컨텍스트를 첨부 .bind하면 컨텍스트가 이미 첨부되어 있습니다.
Rafa Romero

2
@Rafa 로메로 당신이 그들 중 하나를 사용할 수 있습니다, 단지 세 가지 옵션입니다
올렉산드르 T.

2
이제 공식 React Docs 웹 사이트에이 질문에 대한 자세한 답변이 나와 있습니다
zenoh

2

이 동작은 React가 클래스 기반 구성 요소의 릴리스를 발표했을 때 문서화되었습니다.

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

자동 바인딩

React.createClass에는 모든 메소드를 자동으로 바인딩하는 내장 매직 기능이 있습니다. 다른 클래스에서이 기능에 익숙하지 않은 JavaScript 개발자에게는 약간 혼란 스러울 수 있으며 React에서 다른 클래스로 이동할 때 혼란 스러울 수 있습니다.

따라서 우리는 React의 클래스 모델에이 기능을 내장하지 않기로 결정했습니다. 원하는 경우 생성자에서 메서드를 명시 적으로 미리 바인딩 할 수 있습니다.


2

이 게시물이 이미 몇 년 전이라는 것을 알고 있지만, https://reactjs.org/tutorial/tutorial.html 에서이 일반적인 실수에 대한 최신 React 튜토리얼 / 문서를 참조하기 위해 (저도 그렇게했습니다) :

노트

타이핑을 줄이고 혼란스러운 동작을 피하기 위해 여기와 아래에서 이벤트 핸들러에 화살표 함수 구문을 사용합니다.

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')}을 작성하는 것은 일반적인 실수이며 구성 요소가 다시 렌더링 될 때마다 경고를 발생시킵니다.


1

방법을 전달하는 방법 this.activatePlaylist(playlist.playlist_id) 은 즉시 메서드를 호출합니다. 메서드의 참조를 onClick이벤트에 전달해야합니다 . 아래 언급 된 구현 중 하나를 따라 문제를 해결하십시오.

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

여기서 bind 속성은 다음 this.activatePlaylist을 전달 하여 메서드 의 참조를 만드는 데 사용됩니다.this 컨텍스트와 인수playlist.playlist_id

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

이렇게하면 사용자 클릭 동작에서만 트리거되는 onClick 이벤트에 함수가 연결됩니다. 이 코드가 예상되면 this.activatePlaylist메서드가 호출됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.