<!-- HTML 버전 -->
<button onclick="activateLasers()">
Activate Lasers
</button>
<!-- React 버전 -->
<button onClick={activateLasers}>
Activate Lasers
</button>
React에서 이벤트 핸들러를 등록할 때 두 가지 주요 방법
- 화살표 함수로 이벤트 핸들러 전달: onKeyDown={(e) => handleInputKeyBoardEvent(e)}
- 직접 이벤트 핸들러를 전달: onKeyDown={handleInputKeyBoardEvent}
첫 번째 방법은 화살표 함수 내에서 이벤트 핸들러를 호출한다. 이 경우, 매 호출마다 새로운 함수가 생성되기 때문에 성능 면에서 약간의 오버헤드가 발생할 수 있다. 그러나 이 차이는 작고 미비하며, 대부분의 경우에서는 무시할 수 있을 만큼 작다.
두 번째 방법은 함수를 직접 전달한다. 이는 함수를 호출하는 게 아니라 해당 함수의 참조를 전달하는 하게 된다. React는 내부적으로 이벤트 핸들러에 전달된 함수를 알아서 적절히 처리하며, 이 경우에도 이벤트 객체가 제대로 전달된다.
따라서 두 가지 방법 모두 동작하며, 주된 차이는 성능 측면에서 매우 미세하고, 일반적으로는 무시할 수 있을 정도이지만, 코드를 더 간결하게 작성하고자 한다면, 두 번째 방법을 사용하는 것이 좋다.
모든 이벤트 핸들러에는 해당 이벤트에 대한 정보를 담고 있는 이벤트(event) 객체(e 또는 event
)가 매개변수로 전달된다.
e
의 객체 구조 (console.log(event))
event.target
의 객체 구조 (console.log(event.target))
event.target.value
의 객체 구조 (console.log(event.target.value))
이벤트의 기본 동작을 방지하려면 event.preventDefault
를 명시적으로 호출해야 한다.
onChange
이벤트는 input(text, checkbox, radio)
, select
, textarea
요소의 값이 입력되었을 때 발생한다.
onChange
이벤트가 발생하면 e.target.value
를 통해 이벤트 객체에 담겨있는 input
값을 읽어올 수 있다.
onChange
는 input
의 텍스트가 바뀔 때마다 발생하는 이벤트이다. 이벤트가 발생하면 handleChange
함수가 작동하며, 이벤트 객체에 담긴 input
값을 setState
를 통해 새로운 `state``로 갱신한다.
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value);
}
return (
<div>
<input type="text" value={name} onChange={handleChange}></input>
</div>
)
};
input
의 텍스트가 바뀔 때마다 이벤트가 발생한다.onClick
이벤트는 사용자가 마우스 버튼을 클랙했을 때 발생한다.
버튼이나 <a>
태그를 통한 링크 이동 등과 같이 주로 사용자의 행동에 따라 애플리케이션이 반응해야 할 때 자주 사용한다.
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value);
}
return (
<div>
<input type="text" value={name} onChange={handleChange}></input>
// 버튼을 클릭하면 input에 입력한 값이 alert 창으로 뜬다.
<button onClick={() => { handleChange(); alert(name) }}>Button</button>
</div>
);
};
하나의 이벤트에서 여러개의 이벤트 함수 동시에 실행하기
- 화살표 함수(
() => {}
)를 사용하며 함수에는()
를 붙여주고 함수마다 세미콜론(;
)으로 구분해준다.onClick={() => { handleChange(); alert(name) }}
이벤트 핸들러에 함수를 직접 호출하면 안 되는 이유
일반적으로 이벤트 핸들러에 함수를 직접 호출하는 방식인
onClick={getSelectDetailData(word)}
를 사용하면 안 되는 이유는 아래와 같다.
onClick={getSelectDetailData(word)}
라고 작성하면 페이지가 렌더링될 때getSelectDetailData(word)
가 즉시 실행된다. 즉, 이벤트 핸들러로 할당되는 것이 함수의 반환 값이 아니라, 함수 호출 자체가 된다. 원하는 것은 클릭 이벤트가 발생했을 때 함수를 실행해야 하는데, 이렇게 작성하면 페이지가 로드될 때 함수가 즉시 실행되어 원하는 시점에 실행되지 않고 초기 렌더링 시에만 실행되게 된다.그러나
onClick={() => getSelectDetailData(word)}
와 같이 화살표 함수를 사용하면 화살표 함수 내에서getSelectDetailData(word)
를 호출하므로 클릭 이벤트가 발생했을 때 함수가 실행된다.
이벤트 핸들러에 함수 호출을 바로 전달하는 것보다 화살표 함수를 사용하여 해당 함수를 호출하면, 이벤트가 발생했을 때 함수가 실행되도록 보장할 수 있다.
모든 키를 눌렀을 때 발생한다.
onKeyDown
이벤트와 마찬가지로 control, option, shift, tab, delete, enter, 방향 키와 문자, 숫자, 특수 문자 키를 놓았을 때 발생한다. 단, 문자, 숫자, 특수 문자, enter키를 눌렀을 때는 연속적으로 발생하지만 그 외의 키를 눌렀을 때는 한 번만 발생한다.
onKeyUp
이벤트는 누르고 있던 키를 놓았을 때 한 번만 발생한다.
onKeyDown
이벤트와 마찬가지로 control, option, shift, tab, delete, enter, 방향 키와 문자, 숫자, 특수 문자 키를 놓았을 때 발생한다.
한글 입력 후 Enter키 입력 시 중복으로 입력되는 현상
- 영어가 아닌 한글 입력 후 Enter키 입력 시 중복으로 이벤트가 실행되는 현상이 발생하는데 이 경우 조건식에
event.nativeEvent.isComposing === false
를 추가해준다.const handleKeyupTodoText = (event) => { if (event.key === 'Enter' && event.nativeEvent.isComposing === false) { addTodoText(); } };
- 이벤트가 중복 실행되는 에러