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가 권장하는 이벤트 바인딩 방법
    ```js
    // 생성자에서 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](https://reactjs.org/docs/handling-events.html)  
> [The best way to bind event handlers in React](https://medium.freecodecamp.org/the-best-way-to-bind-event-handlers-in-react-282db2cf1530)


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

- [예제 코드](https://codesandbox.io/s/nrjwy3210j)  

> [What's the difference between “super()” and “super(props)” in React](https://stackoverflow.com/questions/30571875/whats-the-difference-between-super-and-superprops-in-react-when-using-e)


## 컴퍼넌트 간의 데이터 교환
```js
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