[나를 위한 React공식 문서 번역] 6. Handling Events이벤트 다루기

Sanghoon Han·2021년 7월 17일
0
post-thumbnail

Handling Events

events를 리엑트로 hanlding하는 것은 정말 기존의 DOM elements들을 handling하는 것과 유사해!!
몇몇 문법만 조금 달라~

  • 리엑트의 event들은 camelCase써 소문자로 작성하기 보단.
  • 너가 event handler로써 JSX에 함수를 전달해 string값 대신에

HTML 예시

HTML

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

리엑트에선 아주 약간 달라

javascript

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

또다른 차이는 너가 default behavior를 리엑트에서 막기위해 return값으로 false를 줄 수 없어
넌 무조건 preventDefault를 무조건 명시적으로 호출을 해야해
예를 들어볼께 HTMl에선 default값을 막기위해 너는 아래와 같이 작성할수 있어

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

리엑트에선 반드시 아래처럼 작성해야해

javascript
function Form() {
	function handleSubmit(e) {
    e.preventDefault();
    console.log('You clicked submit.');
	}
  	return (
    	<form onSubmit={handleSubmit}>
        	<button type="submit">Submit</button>
        </form>
    );
}

여기서 e 란 synthetic(종합적인) event야. 리엑트는 이러한 synthetic events를
W3C spec에 맞게 정의했어. 그래서 너가
cross-browser호환성에 관해 굳이 걱정할 필요없어!

React events는 기존 native event들과 완전히 같게 작동하지는 않아.
링크를 보면 이거에 대해 잘알꺼야

리엑트를 사용할때, 넌 일반적으로 Dom이 만들어지고 거기에 listener를 달기 위해 addEventListener를 호출할 필요 없어. 대신에 단지 listener를 그 element가 초기에 랜더링 될때 제공하면 돼.

너가 component를 es6 class를 사용해서 정의한다면, event handler를 class내부에 method로 하는것이 일반적인 패턴이야.

예를 들면, 이 Toggle component는 button을 랜더링 해 그리고 이 버튼은 user 이 on상태와 OFF상태 사이를 toggle할 수 있게 해. 아래코드를 한번 봐보자

javascript
class Toggle extends React.Component {
	constructor(props) {
    	super(props);
       	this.state = {isToggleOn: true};
        //여기서 this를 bind하는 이유는 callback함수 내에서 this가 이 Toggle instance를 지정하게 하기 위해서야!!
        this.handleClick = this.handleClick.bind(this);
    }
    handleClick() {
    	this.setState(prevState =>({
        	isToggleOn: !prevState.isToggleOn
        }));
    }
    
    render() {
    	return (
        	<button onClick={this.handleClick}>
            	{this.state.isToggleOn ? "ON" : 'OFF'}
            </button>
        );
    }
}

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

Code펜에서 작성해보기 !

너가 JSX 내부에 callback함수 내에서 this를 사용할때 주의를 해야해
자바스크립트에선 class 메서들은 default로 bind되어있지 않아. 만약 너가 this를 this.handleClickdㅔ서 bind해주는걸 까먹으면, 이 함수가 호출될때 this는 undefined가 될꺼야

this는 React만의 특별한 기법이 아니야. 이건 어떻게 자바스크립트안에서 함수가 작동하는지를 알아야해
이 링크를 참고해봐!
일반적으로 만약 너가 ()없이 method를 작성한다면, 예를들면 onClick={this.handleClick}, 넌 무조건 이 메서드에 this를 bind시켜줘야해.

만약 너가 함수에 bind를 쓰는걸 선호하지 않다면, 너가 이 this문제를 극복하는 두가지 방법이 있어.
만약 너가 아직은 실험적인 public class field syntax를 사용한다면 넌 이 class에서
this가 완전히 callback으로 전달해도 잘 작동되는걸 볼 수 있어

class LoggingButton extends React.Component {
  // 여기서 this는 handleClick에 아주 잘 bind 되있어
  // Warning: 주의!!! 근데 이건 실험적인 문법이야  
  handleClick = () => {
    console.log('this is:', this);
  }

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

이 문법은 Create React App에서 기본값으로 사용 가능하게 되있어

근데 class field문법을 너가 사용하지 않는다면 넌 arrow function(es6)를 callback함수로 주는 방법이 있어

javascript

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

  render() {
    //이 문법은 this를 handleClick에 bind되게 보장해줘!
    return (
      <button onClick={() => this.handleClick()}>
        Click me
      </button>
    );
  }
}

이 syntax(문법)의 문제는 다른 callback이 LogginButton이 랜더 될때마다 생성되어져
대부분의 경우에는 괜찮아
근데 만약 이 callback을 더 낮은 컴포넌트에 prop으로 전달한다면 그런 component들은 아마 추가적으로 re-rendering될꺼야. 우리는 일반적으로 constructor에 bind를 해주거나 아니면 class field syntax를 하용하는 방법을 추천해. 위와 같은 퍼포먼스 적인 문제를 피하기 위해서

Event Handler들에 aruments전달하기

괄호 안에 추가적인 파라미터들을 이벤트 핸들러로 전달하는게 일반적이야.
예를 한번 보자. 만약 id가 아주 기본ID이고 아래와 같은 작업을 한다고 해

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

그 위 두개의 버튼은 똑같아 첫번째는 arrow function을 활용했고 두번째는 Function.prototype.bind를 활용했어.

두가지 경우 모두, 그 e 인자는 그 리엑트 이벤트가 두번째 argument로 전달되 id이후에, arrow함수에선 우리는 이걸 명시적으로 전달을 해줘야하고, bind의 경우 추가적인 arguments들은 자동적으로 뒤로 전달되.

Reference

https://reactjs.org/docs/handling-events.html

profile
Fail Fast learn Faster

0개의 댓글