React/React 문법

[React]이벤트 핸들러 바인딩(Event Handler Binding)

DevStory 2021. 7. 7.

이벤트 핸들러 바인딩이란?

컴포넌트(Component)이벤트 함수연결(bind)하는 것입니다.

바인딩하지 않아도 이벤트 함수는 실행이 되지만, 누가(어떤 컴포넌트가) 호출을 했는지 알 수 없습니다.

바인딩하지 않았는데, 이벤트 함수에서 this.state 또는 this.props를 사용할 경우 undefined로 처리됩니다.


바인딩하지 않고 이벤트 함수에서 this를 사용하는 경우

class TestComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { applyText: "빈 값" };
  }
 
  NotBindingBtnClick() {
    console.log(this.state.applyText);
  }
 
  render() {
    return (
      <React.Fragment>
        <button type="button" onClick={this.NotBindingBtnClick}>
          NotBinding
        </button>
      </React.Fragment>
    );
  }
}

내가 생각하는 로직

TestComponent의 생성자(constructor)가 실행되면서 state.applyText의 값이 "빈 값"으로 초기화

→ TestComponent Render 완료

→ TestComponent에서 버튼을 클릭

→ NotBindingBtnClick 이벤트 함수 실행

→ console.log에서 this.state.applyText 값 확인

 

내가 생각하는 결과

"빈 값"

 

실제 결과

undefined


undefined가 출력된 이유?

nullundefined에 대해 헷갈리시는 분들은 클릭해주세요.

 

JS에서 undefined는 변수 또는 객체의 속성이 존재하지 않을 경우입니다.

null과 비교를 해서 설명하자면, null은 변수는 존재하지만 값이 없는 경우이고 undefined는 변수가 존재하지 않는 경우입니다.

 

이벤트 함수에서 사용한 thisTestComponent를 의미합니다.

JSX this(=TestComponent)bind하지 않습니다.

컴포넌트의 이벤트 함수에서 this를 사용할 경우 생성자(constructor)에서 bind 하거나 arrow function을 사용해야 합니다.

 

arrow function는 정적으로 bind 되는 게 아니라 함수가 어떻게 호출되었는지에 따라서 바인딩할 객체가 동적으로 결정됩니다.


이벤트 함수에서 this를 사용하는 방법

이벤트 함수에서 가변 상태(this.state)에 접근하는 방법입니다.

 

1) 생성자(constructor)에서 바인딩

이벤트 함수가 많아질수록 코드가 길어지는 문제가 있습니다.

class TestComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { applyText: "빈 값" };
 
    this.NotBindingBtnClick = this.NotBindingBtnClick.bind(this);
  }
 
  NotBindingBtnClick() {
    console.log(this.state.applyText);
  }
 
  render() {
    return (
      <React.Fragment>
        <button type="button" onClick={this.NotBindingBtnClick}>
          NotBinding
        </button>
      </React.Fragment>
    );
  }
}

 

2) 화살표 함수 사용 방법 1.

class TestComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { applyText: "빈 값" };
  }
 
  NotBindingBtnClick = () => {
    console.log(this.state.applyText);
  }
 
  render() {
    return (
      <React.Fragment>
        <button type="button" onClick={this.NotBindingBtnClick}>
          NotBinding
        </button>
      </React.Fragment>
    );
  }
}

 

3) 화살표 함수 사용 방법 2.

class TestComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { applyText: "빈 값" };
  }
 
  render() {
    return (
      <React.Fragment>
        <button type="button" onClick={this.NotBindingBtnClick = () => {console.log(this.state.applyText);}}>
          NotBinding
        </button>
      </React.Fragment>
    );
  }
}

 

4) 화살표 함수 사용 방법 3.

class TestComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { applyText: "빈 값" };
  }
 
  NotBindingBtnClick = () => {
    console.log(this.state.applyText);
  }
  render() {
    return (
      <React.Fragment>
        <button type="button" onClick={() => this.NotBindingBtnClick()}>
          NotBinding
        </button>
      </React.Fragment>
    );
  }
}

 

5) 이벤트 선언과 바인딩

class TestComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { applyText: "빈 값" };
  }
 
  NotBindingBtnClick = () => {
    console.log(this.state.applyText);
  }
 
  render() {
    return (
      <React.Fragment>
        <button type="button" onClick={this.NotBindingBtnClick.bind(this)}>
          NotBinding
        </button>
      </React.Fragment>
    );
  }
}

 

6) Hook을 이용한 Arrow Function Component

Hook을 이용하여 함수형 컴포넌트를 구현할 경우 생성자(constructor)가 필요 없으며, this를 사용하지 않아도 됩니다.

const TestComponent () => {
   const [applyText, setApplyText] = useState('빈 값');
 
  return (
    <React.Fragment>
      <button type="button" onClick={() => console.log({applyText})}>
        NotBinding
      </button>
      <ListComponent applyText={applyText} />
    </React.Fragment>
  );
}

 

반응형

댓글