8강. Handling Events
Event란?
● 이벤트 = 사건
● 특정 사건을 의미
ex) 사용자가 버튼을 클릭한 사건 => 버튼 클릭 이벤트
● 웹사이트에는 다양한 이벤트들이 있는데,
이 이벤트들이 발생했을 때 원하는대로 잘 처리해주어야 웹사이트가 정상적으로 돌아갈 수 있습니다.
● 이벤트를 처리하는 것을 이벤트를 handling 한다고 표현
DOM의 Event
<DOM에서 클릭 이벤트를 처리하는 예제 코드>
<button onclick="activate()">
Activate
</button>
버튼이 눌리면 Activate라는 함수를 호출
-> DOM에서는 클릭 이벤트를 처리할 함수를 onclick을 통해 전달
리액트의 Event
<button onClick={activate}>
Activate
</button>
위의 DOM의 Event 예제코드와 동일한 기능을 하도록 만든 리액트 코드
DOM의 Event와 리액트의 Event 차이점
1. 표기법의 차이
이벤트의 이름에서 C가 대문자로 되어있는 onClick으로 되어있습니다. (camelCase 카멜 표기법)
2. 함수 전달 방식의 차이
DOM에서는 Event를 처리할 함수를 문자열로 전달하지만, 리액트에서는 함수 그대로 전달합니다.
camelCase(카멜표기법)이란?
● 카멜표기법은 낙타의 등의 모양을 보고 이름을 지은 것
● 낙타의 등에 굴곡진 혹이 있어서 오르락 내리락하는 모양처럼,
첫 글자는 소문자로 시작하되 중간에 나오는 새로운 단어의 첫 글자를 대문자로 사용하여 글자의 크기가 변하는 것이 낙타의 등과 같다고 해서 지어진 이름
Event Handler
어떤 이벤트가 발생했을 때 해당 이벤트를 처리하는 함수
: 어떤 사건이 발생하면, 사건을 처리하는 역할
Event Handler는 이벤트가 발생하는 것을 계속 듣고 있는다는 의미로, Event Listener라고 부르기도 합니다.
Event Handler 사용 방법
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = { isToggleOn: true };
// callback에서 `this`를 사용하기 위해서는 바인딩을 필수로 해줘야 합니다.
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? '켜짐' : '꺼짐'}
</button>
);
}
}
▲ Toggle이라는 클래스 컴포넌트
● 컴포넌트의 state에는 isToggleOn이라는 분리형 변수가 하나 있습니다.
● 버튼을 클릭하면 Event Handler 함수인 handleClick()를 호출하도록 되어있습니다.
handleClick() 함수의 정의와 bind
● handleClick() 함수를 정의하는 방법은 일반적인 함수를 정의하는 것과 동일하게 괄호와 중괄호를 사용해서 클래스의 함수로 정의하고 있습니다.
● 이렇게 정의해준 함수를, constructor에서 bind를 이용하여 this.handleClick에 대입해줍니다.
Bind하는 이유? 자바스크립트에서는 기본적으로 클래스함수들이 바운드되지 않기 때문 - 바인드하지 않으면 this.handleClilck은 global scope에서 호출되는데, global scope에서 this.handleClilck은 undefind이므로 사용할 수 없습니다.
리액트에만 해당되는 것이 아니라 자바 스크립트 작동 원리의 일부분
: 일반적으로 함수의 이름 뒤에 괄호 없이 사용하려면 무조건 해당 함수를 바인드해주어야 함
▼ bind 참고 링크
Function.prototype.bind() - JavaScript | MDN
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
developer.mozilla.org
다른 방법들
● bind를 사용하는 방식이 번거롭게 느껴진다면, 아래 예제 코드처럼 Class fields syntax를 사용할수도 있습니다.
class MyButton extends React.Component {
handleClick = () => {
console.log('this. is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
클릭
</button>
);
}
}
● bind도 사용하지 않고 Class fields syntax도 사용하지 않으려면,
아래 예제 코드처럼 event handler를 넣는 곳에 Arrow function을 넣는 방법도 있습니다.
class MyButton extends React.Component {
handleClick() {
console.log('this is:', this);
}
render() {
// 이렇게 하면 `this`가 바운드됩니다.
return (
<button onClick={() => this.handleClick()}>
클릭
</button>
);
}
}
이 방식은 MyButton 컴포넌트가 렌더링될 때 마다 다른 callback 함수가 생성되는 문제가 있습니다.
대부분의 경우에는 상관없지만, 이 callback 함수가 하위 컴포넌트의 props로 넘겨지게 되면 하위 컴포넌트에서 추가적인 렌더링이 발생 -> 성능문제가 발생할 수 있습니다.
함수 컴포넌트에서 이벤트 처리 방법
function Toggle(props) {
const [isToggleOn, setIsToggleOn] = useState(true);
// 방법 1. 함수 안에 함수로 정의
function handleClick() {
setIsToggleOn((isToggleOn) => !isToggleOn);
}
// 방법 2. arrow function을 사용하여 정의
const handleClick = () => {
setIsToggleOn((isToggleOn) => !isToggleOn);
}
return (
<button onClick={handleClick}>
{isToggleOn ? "켜짐" : "꺼짐"}
</button>
);
}
함수 컴포넌트 내부에서 event handler를 정의하는 방법
방법 1. 함수 안에 함수로 정의
방법 2. arrow function을 사용하여 정의
함수 컴포넌트에서는 event를 넣어줄 때 this를 사용하지 않고
<button onClick={handleClick}>
처럼 onClick에 곧바로 정의한 event handler를 넣어주면 됩니다.
Arguments 전달하기
Argument?
= 주장
함수에 주장할 내용
= 함수(event handler)에 전달할 데이터
Argument = Parameter (매개변수)
매개변수를 전달해야 하는 경우?
ex) 특정 사용자 프로필을 클릭했을 때, 해당 사용자의 아이디를 매개변수로 전달해서 정해진 작업을 처리해야 하는 경우
어떻게 매개변수를 event handler에 전달할까? (클래스 컴포넌트)
<button onClick={(event) => this.deleteItem(id, event)}>삭제하기</button>
<button onClick={this.deleteItem.bind(this, id)}>삭제하기</button>
▲ 이 코드 두 줄은 모두 동일한 역할을 하지만, 하나는 arrow function을 사용하고 다른 하나는 bind를 사용
event라는 매개변수는 리액트의 이벤트 객체를 의미
두 방법 모두 첫 번째 매개변수는 id이고, 두 번쨰 매개변수로 event가 전달됩니다.
- 첫 번째 줄의 arrow function을 사용한 방법은 명시적으로 event를 두 번쨰 매개변수로 넣어주었고, 두 번째 줄의 bind를 사용한 방법은 event가 자동으로 id 이후에 두 번째 매개변수로 전달됩니다.
(이 방식들은 클래스 컴포넌트에서 사용되는 방법이므로 현재는 거의 사용하지 않습니다.)
어떻게 매개변수를 event handler에 전달할까? (함수 컴포넌트)
function MyButton(props) {
const handleDelete = (id, event) => {
console.log(id, event.target);
};
return (
<button onClick={(event) => handleDelete(1, event)}>
삭제하기
</button>
);
}
'개발공부 > REACT' 카테고리의 다른 글
Conditional Rendering의 정의, JavaScript의 Truthy와 Falsy, Element Variables의 개념, Inline Conditions [처음 만난 리액트 #26] (0) | 2023.02.16 |
---|---|
클릭 이벤트 처리하기 실습 [처음 만난 리액트 #25] (1) | 2023.02.11 |
Hooks 사용해보기 실습 (useState, useEffect Hook 사용, Custom hook 만들기) [처음 만난 리액트 #23] (0) | 2023.02.06 |
[Java] 자바 JDK 삭제/설치 방법 (Java 버전 11) (0) | 2023.02.06 |
Hooks의 규칙과 Custom Hook 만들기 [처음 만난 리액트 #23] (0) | 2023.02.05 |