beecomci / today_i_learned

0 stars 0 forks source link

[React-Basic-Hooks] 6. React event handling #10

Open beecomci opened 3 years ago

beecomci commented 3 years ago

React event handling #

React event delegation

image

beecomci commented 3 years ago

React의 이벤트 시스템

React 적용 가이드 - React 작동 방법 글은 React 17 이전 버전에 대한 내용이 대부분 17 버전부터는 Event Pooling 방식 미사용 + 이벤트가 등록되는 엘리먼트가 document에서 root로 변경된 것을 제외하고 기본적인 이해만 돕고자 Event Delegation과 React syntheticEvent 객체만 정리함

추가 참고 문서

Event Delegation

버블링(Bubbling)

<div class="one">
  one
    <div class="two">
      two
    <div class="three">
          three
    </div>
    </div>
</div>
var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
  div.addEventListener('click', logEvent);
});

function logEvent(event) {
  console.log(event.currentTarget.className);
}

캡쳐링(Capturing)

var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
  // addEventListener API에서 옵션 객체에 capture:true 설정 -> 해당 이벤트 감지하기 위해 버블링과 반대 방향으로 탐색
  div.addEventListener('click', logEvent, { capture: true });
});

function logEvent(event) {
  console.log(event.currentTarget.className);
}

event.stopPropagation()

SyntheticEvent

function Form() {
  function handleSubmit(e) {
    e.preventDefault();
    console.log('You clicked submit.');
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}

이벤트 핸들러 사용시 this 주의점

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // 1. 콜백에서 `this`가 작동하려면 아래와 같이 바인딩 해주어야 합니다.
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  // 2. this가 handleClick 내에서 바인딩 되도록
  render() {
    return (
      <button onClick={() => this.handleClick()}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
  /*render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }*/
}

ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);

1. bind 호출

2. arrow function 사용

이벤트 핸들러에 인자 전달

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>