지금까지 정적인 상태를 조작하는 방법에 대해서 다뤘다.
특정 CSS를 만져서 조금 더 날것 그대로의 느낌에서 벗어날 수는 있었다.
하지만, 웹사이트에서 사진처럼 고정된 것을 보기 위해서 웹사이트를 보는 것은 아닐 것이다.
그렇기에 이번 시간에는 사용자의 반응인 event와 그 event가 발생할 때 동작되는 event handler에 대해서 이야기 해볼 것이다.
event란?
이벤트(event)란 프로그래밍하고 있는 시스템에서 일어나는 사건(action)을 말한다.
예를 들자면, 만약 사용자가 웹페이지에 있는 버튼을 고른다면, 그 버튼 누루는 사건에 대해서 숫자를 증가시킨다거나 좋아요를 누르게끔 응답하길 원할 수 있을 것이다.
- 유저가 어떤 요소를 선택하거나 어떤 요소 위에 커서를 올려둔다(hover).
- 유저가 키보드에서 키를 입력한다(push).
- 유저가 브라우저 창의 크기를 재조정하거나 닫는다.
- 웹 페이지가 로딩을 완료했다.
- 양식(form)이 제출되었다.
- 비디오가 재생되거나, 멈추거나, 혹은 끝났다. 오류가 발생했다.
Event Handler[Listener]란?
위에서 언급한 여러 event들은 이벤트 핸들러(event handler)를 가지고 있는데, 이는 event가 발생되면 실행되는 코드 블럭을 의미한다. 그러한 코드 블럭이 이벤트에 응답해서 실행되기 위해 정의되었을 때, 우리는 event를 등록(register)했다고 말한다. 경우에 따라 event listener라고 불리기도 한다. 구체적으로는 listener는 발생되는 event를 듣고, handler는 발생되는 event에 응답해서 실행되는 코드입니다.
React에서는 JSX로 작성된 HTML 코드들을 표준 JS로 변환해줬던 것과 마찬가지로 event listener도 변환해주며, 기본적인 모든 이벤트를 on으로 시작하는 props로 노출한다.
이때에 기억해야할 것은 onClick
과 같이 on 다음 event 명은 대문자로 시작한다는 것이다.
그 값은 중괄호{}로 묶에서 표현해준다.
<button onClick={() => {console.log('Click!'}}>Button<button>
위와 같이 표현하면, 버튼이 클릭되었을 때 함수를 실행해줄 것이다.
물론 Arrow Function이 아니더라도 사용할 수는 있다.
하지만 수많은 코드들을 JSX block 안에 넣는다는 것은 좋은 아이디어가 아닐 것이다.
일반적으로 생각해보았을 때에도 가독성이 떨어지며, 깔끔해보이지 않는다.
그래서 JSX 코드에는 너무 많은 로직을 원치 않는다.
대신, 많은 경우에 아래와 같이 값을 반환하기 전에 함수를 정의해서 사용한다.
const ExpenseItem = (props) => {
const clickHandler = () => {
console.log("click!!!!") ;
}
return (
<Card className="expense-item">
<ExpenseDate date={props.date}/>
<div className="expense-item__description">
<h2>{props.title}</h2>
<div className="expense-item__price">${props.amount}</div>
</div>
<button onClick={clickHandler}>Change Title</button>
// <button onClick={clickHandler()}>Change Title</button> don't used
</Card>
);
}
위의 코드를 자세히 보면, clickHandler를 괄호()를 넣지 않는 모습니다.
만약, 여기에 괄호가 추가되어 있었다면 JSX 코드가 JS로 반환될 때 이 코드 라인이 분석될 것이고, 이 때에 JavaScript는 이 함수를 실행할 것이다. 이는 사용자가 웹사이트에서 해당 버튼을 클릭했을 때 clickHandler가 실행되지 않는다는 것이다.
따라서 JSX 코드로 작성할 때에는 clickHandler라고 함수만 지정하면 된다.
onClick을 위한 값으로 pointer를 전달하고 React가 기본적으로 이것을 기억했다가 클릭할 때마다 함수를 실행한다.
모든 내장된 HTML 요소(tag)에 지원되는 event listener를 추가할 수 있다.
일부 event는 특정한 요소에서만 사용 가능하지만 기본적인 DOM 동작에 기반한다.
또한, event 함수에 대해서 이름 지을 때에는 event의 트리거로 시작해서 Handler로 끝나게끔 명명하는 관례가 있다.
이것은 반드시 이렇게 해야하는 것은 아니고 모든 개발자들이 이렇게 하는 것은 아니지만 함수를 호출할 때 이것이 무슨 함수인지를 알게하기 위함이 아닐까? 많은 코드를 작성하다보면 해당 함수가 어디서 왔는가라는 고민이 들 때가 있다. 이렇게 헷갈리는 것을 방지하기 위함일 것이라는 생각이 든다.
출처