React 기초

[React] 이벤트 처리하기 (5)

Evolving Developer 2023. 2. 8. 00:39

HTML과 React 문법 차이

1. 이벤트 처리

HTML 문법

<button onclick="activateLasers()">
  Activate Lasers
</button>

React 문법

- ( ) 괄호 떼기

- { } 중괄호로 감싸기

<button onClick={activateLasers}>
  Activate Lasers
</button>

2. preventDefault()

- React는 false를 반환해도 기본 동작 방지 불가능

- 반드시 preventDefault 명시적 호출

HTML 문법

<form onsubmit="console.log('You clicked submit.'); return false">
  <button type="submit">Submit</button>
</form>

React 문법

- e : 합성 이벤트 -> 브라우저 호환성 걱정 ❌

function Form() {
  function handleSubmit(e) {
    e.preventDefault(); // 기본 동작을 방지해줌 ex) 제출
    console.log('You clicked submit.');
  }

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

On / Off 버튼 만들기

 render() {
    return (
      <button onClick={this.handleClick}> // 바인딩 필요
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }

- Js에서 클래스 메서드는 기본적으로 바인딩 ❌

- 바인딩하지 않으면 this.handleClick이 호출될 때 this는 undefined...

 constructor(props) {
    super(props);
    this.state = {isToggleOn: true}; // state 초기 상태를 true로 설정
    this.handleClick = this.handleClick.bind(this); // 중요) 바인딩
  }

전체 코드

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true}; // state 초기 상태를 true로 설정
    this.handleClick = this.handleClick.bind(this); // 중요) 바인딩
  }

  handleClick() {
    this.setState(prevState => ({ // 기존 상태를 인자로 받는 setState()
      isToggleOn: !prevState.isToggleOn // true <-> false 변환
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}> // 이벤트 핸들러 설정
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

bind 호출이 불편하다면

1. 퍼블릭 클래스 필드 문법

class LoggingButton extends React.Component {
  // 이 문법은 `this`가 handleClick 내에서 바인딩되도록 합니다.
  // 주의: 이 문법은 *실험적인* 문법입니다.
  handleClick = () => {
    console.log('this is:', this);
  };

2. 콜백에 화살표 함수 사용

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // 이 문법은 `this`가 handleClick 내에서 바인딩되도록 합니다.
    return (
      <button onClick={() => this.handleClick()}>
        Click me
      </button>
    );
  }
}

- 문제) LogginButton이 렌더링될 때마다 다른 콜백이 생성됨

- 생성자 안에서 바인딩하거나 클래스 필드 문법 사용 권장


이벤트 핸들러에 인자 전달하기

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button> // 화살표 함수

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

- 두 경우 모두 React 이벤트를 나타내는 e 인자가 id 뒤에 두 번째 인자로 전달됨

- 화살표 함수의 경우 명시적으로 전달해야 하지만

- bind를 사용할 경우 추가 인자가 자동으로 전달됨