1. 이벤트 핸들러 추가하기
2. 이벤트 전파
3. 이벤트 핸들러에 부작용이 생길 수 있을까?
// 예시
export default function Button() {
return (
<button>
I don't do anything
</button>
);
}
Button
컴포넌트 안에 handleClick
이라는 함수를 선언한다.alert
을 사용하여 메시지 표시).<button>
에 onClick={handleClick}
를 추가한다.export default function Button() {
function handleClick() {
alert('You clicked me!');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
handleClick
함수를 정의한 다음 이를 <button>
에 prop으로 전달했다.
(handleClick
은 이벤트 핸들러이다.)
handle
로 시작하는 이름 뒤에 이벤트 이름이 오도록 한다.관례상 이벤트 핸들러의 이름은 handle
뒤에 이벤트 이름을 붙이는 것이 일반적이다.
흔히 onClick={handleClick}
, onMouseEnter={handleMouseEnter}
등을 볼 수 있다.
또는 JSX에서 인라인으로 이벤트 핸들러를 정의할 수도 있다.
// 예시
<button onClick={function handleClick() {
alert('You clicked me!');
}}>
// 예시
<button onClick={() => {
alert('You clicked me!');
}}>
주의
- 이벤트 핸들러에 전달되는 함수는 호출하는 게 아니라 전달되어야 한다.
- 함수 전달 (올바름)
<button onClick={handleClick}>
- 함수 호출 (잘못됨)
<button onClick={handleClick()}>
- 차이점은 미세하다.
- 함수 전달에서는
handleClick
함수가onClick
이벤트 핸들러로 전달된다.
이렇게 하면 React가 이를 기억하고 사용자가 버튼을 클릭할 때만 함수를 호출하도록 지시한다.- 함수 호출에서
handleClick()
끝에 있는()
은 클릭 없이 렌더링 중에 즉시 함수를 실행한다.
이는 JSX의 { 및 } 내부의 JavaScript가 바로 실행되기 때문이다.
- 인라인 코드 작성 시에도 조심해야한다.
- 함수 전달 (올바름)
<button onClick={() => alert('...')}>
- 함수 호출 (잘못됨)
<button onClick={alert('...')}>
- 이와 같은 인라인 코드를 전달하면 클릭시 실행되지 않고, 컴포넌트가 렌더링될 때마다 실행된다.
<button onClick={alert('You clicked me!')}>
- 이벤트 핸들러를 인라인으로 정의하려면 다음과 같이 익명 함수로 감싸야한다.
<button onClick={() => alert('You clicked me!')}>
- 렌더링할 때마다 내부에서 코드를 실행하는 대신 나중에 호출할 함수를 생성한다.
<button onClick={handleClick}>
은handleClick
함수를 전달한다.
<button onClick={() => alert('...')}>
은() => alert('...')
함수를 전달한다.
화살표 함수 더 알아보기
1-1. 이벤트 핸들러를 props로 전달하기
Button
컴포넌트를 사용하는 위치에 따라 버튼은 동영상을 재생하고 다른 버튼은 이미지를 업로드하는 등 서로 다른 기능을 실행할 떼가 있다.1-2. 이벤트 핸들러 props 이름 정하기
<button>
및 <div>
와 같은 기본 제공 컴포넌트는 onClick
과 같은 브라우저 이벤트 이름만 지원한다.KeyNote
- 이벤트 핸들러에 적절한 HTML 태그를 사용해야 한다.
예를 들어 클릭을 처리하려면<div onClick={handleClick}>
대신<button onClick={handleClick}>
을 사용하라.- 실제 브라우저의
<button>
을 사용하면 키보드 탐색과 같은 기본 브라우저 동작을 사용할 수 있다.- 버튼의 기본 브라우저 스타일이 마음에 들지 않고 링크나 다른 UI 요소처럼 보이길 원한다면, CSS를 사용하여 원하는 방식으로 조정할 수 있다.
접근성 마크업 작성에 대해 자세히 알아보기
<div>
는 2개의 버튼을 포함한다.<div>
와 각 버튼에는 모두 고유한 onClick
핸들러가 있다.// 예시
export default function Toolbar() {
return (
<div className="Toolbar" onClick={() => {
alert('You clicked on the toolbar!');
}}>
<button onClick={() => alert('Playing!')}>
Play Movie
</button>
<button onClick={() => alert('Uploading!')}>
Upload Image
</button>
</div>
);
}
onClick
이 먼저 실행되고 그 다음에 부모 <div>
의 onClick
이 실행된다.<div>
의 onClick
만 실행된다.주의
- 첨부한 JSX 태그에서만 작동하는
onScroll
을 제외한 모든 이벤트는 React에서 전파된다.
2-1. 전파 중지하기
이벤트 핸들러는 이벤트 객체를 유일한 인수로 받는다.
이것은 관례상 “event”를 의미하는 e라고 불립니다.
이 객체를 사용하여 이벤트에 대한 정보를 읽을 수 있습니다.
해당 이벤트 객체를 사용하면 전파를 중지할 수도 있습니다.
이벤트가 상위 컴포넌트에 도달하지 못하도록 하려면 아래 Button
컴포넌트처럼 e.stopPropagation()
을 호출해야 한다.
function Button({ onClick, children }) {
return (
<button onClick={e => {
e.stopPropagation();
onClick();
}}>
{children}
</button>
);
}
export default function Toolbar() {
return (
<div className="Toolbar" onClick={() => {
alert('You clicked on the toolbar!');
}}>
<Button onClick={() => alert('Playing!')}>
Play Movie
</Button>
<Button onClick={() => alert('Uploading!')}>
Upload Image
</Button>
</div>
);
}
<button>
에 전달된 onClick
핸들러를 호출한다.Button
에 정의된 이 핸들러는 다음을 수행한다.e.stopPropagation()
을 호출한다.Toolbar
컴포넌트에서 전달된 props인 onClick
함수를 호출한다.Toolbar
컴포넌트에 정의된 이 함수는 버튼 자체의 경고를 표시한다.<div>
의 onClick
핸들러가 실행되지 않는다.e.stopPropagation()
덕분에 이제 버튼을 클릭하면 두 개의 알림(<button>
과 부모 툴바 <div>
)이 아닌 하나의 알림(<button>
에서)만 표시된다.2-2. 전파의 대안으로 핸들러 전달하기
function Button({ onClick, children }) {
return (
<button onClick={e => {
e.stopPropagation();
onClick();
}}>
{children}
</button>
);
}
onClick
이벤트 핸들러를 호출하기 전에 이 핸들러에 코드를 더 추가할 수도 있다.<button>
과 같은 요소에 함수를 prop으로 전달하여 이벤트를 처리할 수 있다.onClick={handleClick()}
이 아니라 onClick={handleClick}
이다.e.stopPropagation()
을 호출하라.e.preventDefault()
를 호출하자.https://developer.mozilla.org/ko/