React에서 이벤트 다루기

React에서 DOM 이벤트 다루기

  • function vs. Arrow Function
    onClick={ function() { console.log(this) }} // undefiend
    onClick={ () => console.log(this) } // App { ... }

    예제 코드

  • this가 가지는 값

    • function 스코프 내에서 this는 해당 function을 호출한 객체를 this로 한다.
    • 화살표 함수 스코프 내에서 this는 정적(Lexical)영역의 상위 객체를 this로 한다.
  • window가 아닌 undefined가 나오는 이유

    • React는 development 모드에서는 strict mode를 검사하고, production build 에서는 포함되지 않는다.

      Strict Mode

  • 화살표 함수를 사용하면 bind 함수로 바인딩이 필요하지 않다.

    • 화살표 함수 스코프에서 this는 사용된 곳의 상위 객체를 this로 사용하기 때문에 this는 선언된 해당 객체를 가리킨다.

      Arrow Function

  • React가 권장하는 이벤트 바인딩 방법

// 생성자에서 bind()를 사용하는방법
class LoggingButton extends React.Component {
  Constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}

// 사용할 곳에서 bind()를 사용하는 방법
class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleClick.bind(this)}>
        Click me
      </button>
    );
  }
}

// 화살표 함수로 직접 호출하는 방법 
// 이 방법은 LoggingButton이 랜더링 될 때마다 새로운 함수를 생성하는 문제가 있다.
// 콜백 함수 내에서 재랜더링을 발생시키는 경우 성능 문제가 발생할 수 있다.
class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
    );
  }
}

// 화살표 함수로 선언하고 바인딩하는 방법
// 이 방법으로 이벤트를 바인딩 하는것을 권장한다.
class LoggingButton extends React.Component {
  handleClick = () => {
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}

Handling Events
The best way to bind event handlers in React

super() vs super(props)

생성자에서 this를 사용하기 위해서 super(props)를 사용한다.

What's the difference between “super()” and “super(props)” in React

컴퍼넌트 간의 데이터 교환

const ClickCounterButton = props => {
  return (
    <button onClick={props.handler}>Don`t touch me with your dirty hands!</button>
  );
};

class Counter extends React.Component {
  render() {
    return <span>Clicked {this.props.value} thies.</span>;
  }
}

class Content extends React.Component {
  constructor(props) {
    super(props);
    this.state = { counter: 0 };
  }

  handleClick = (event) => {
    this.setState({counter: ++this.state.counter });
  }

  render() {
    return  (
      <div>
        <ClickCounterButton handler={this.handleClick} />
        <br/>
        <Counter value={this.state.counter}/>
      </div>
    )
  }
}

예제 코드

React가 지원하지 않는 DOM 이벤트 처리하기

class Radio extends React.Component {
  constructor(props) {
    super(props);
    let order = props.order;
    let i = 1;
    this.state = {
      outerStyle: this.getStyle(4, i),
      innerStyle: this.getStyle(1, i),
      selectedStyle: this.getStyle(2, i),
      taggerStyle: { top: order * 20, width: 25, height: 25 }
    };
  }
  getStyle(i, m) {
    let value = i * m;
    return {
      top: value,
      bottom: value,
      left: value,
      right: value
    };
  }
  componentDidMount() {
    window.addEventListener("resize", this.handleResize);
  }
  componentWillUnmount() {
    window.removeEventListener("resize", this.handleResize);
  }
  handleResize = event => {
    let w = 1 + Math.round(window.innerWidth / 300);
    this.setState({
      taggerStyle: {
        top: this.props.order * w * 10,
        width: w * 10,
        height: w * 10
      },
      textStyle: { left: w * 13, fontSize: 7 * w }
    });
  };
  render() {
    return (
      <div>
        <div className="radio-tagger" style={this.state.taggerStyle}>
          <input type="radio" name={this.props.name} id={this.props.id} />
          <label htmlFor={this.props.id}>
            <div className="radio-text" style={this.state.textStyle}>
              {this.props.label}
            </div>
            <div className="radio-outer" style={this.state.outerStyle}>
              <div className="radio-inner" style={this.state.innerStyle}>
                <div
                  className="radio-selected"
                  style={this.state.selectedStyle}
                />
              </div>
            </div>
          </label>
        </div>
      </div>
    );
  }
}

예제 코드

React를 다른 라이브러리와 통합하기: jQuery UI 이벤트

https://www.youtube.com/watch?v=AMMetkCvztg