React에서는 JSX에 이벤트 핸들러를 추가할 수 있다.
export default function Button() {
return (
<button>
I don't do anything
</button>
);
}
아무런 동작도 수행하지 않는 버튼에 이벤트 핸들러를 추가하는 과정은 아래와 같다.
handleClick 함수를 선언한다. <button> JSX에 onClick = {handleClick}을 추가한다. export default function Button() {
function handleClick() {
alert('You clicked me!');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
이벤트 핸들러가 갖는 특징
onClick = {handleClick}, onMouseEnter = {handleMouseEnter}이벤트 핸들러로 전달한 함수들은 호출이 아닌 전달되어야 한다.
함수를 전달하기 (올바른 예시) : <button onClick={handleClick}>
함수를 호출하기 (잘못된 예시) : <button onClick={handleClick()}>
인라인으로 코드를 작성할 때에도 마찬가지이다.
함수를 전달하기 (올바른 예시) : <button onClick={() => alert('...')}>
함수를 호출하기 (잘못된 예시) : <button onClick={alert('...')}>
<button onClick={alert('...')}> 이렇게 작성하면, 버튼을 클릭할 때마다 실행되는 것이 아니라 컴포넌트가 렌더링될 때마다 실행된다. function AlertButton({ message, children }) {
return (
<button onClick={() => alert(message)}>
{children}
</button>
);
}
export default function Toolbar() {
return (
<div>
<AlertButton message="Playing!">
Play Movie
</AlertButton>
<AlertButton message="Uploading!">
Upload Image
</AlertButton>
</div>
);
}
function Button({ onClick, children }) {
return (
<button onClick={onClick}>
{children}
</button>
);
}
function PlayButton({ movieName }) {
function handlePlayClick() {
alert(`Playing ${movieName}!`);
}
return (
<Button onClick={handlePlayClick}>
Play "{movieName}"
</Button>
);
}
function UploadButton() {
return (
<Button onClick={() => alert('Uploading!')}>
Upload Image
</Button>
);
}
export default function Toolbar() {
return (
<div>
<PlayButton movieName="Kiki's Delivery Service" />
<UploadButton />
</div>
);
}
전체 구조
Toolbar (부모)
├─ PlayButton
│ └─ Button
└─ UploadButton
└─ Button
Toolbar 컴포넌트가 PlayButton과 UploadButton을 렌더링함. PlayButton은 handlePlayClick을 Button 내 onClick prop으로 전달함.UploadButton은 () => alert('Uploading!')을 Button 내 onClick prop으로 전달함. Button 컴포넌트는 onClick prop을 받고, 이후 받은 prop을 브라우저 빌트인 의 onClick={onClick}으로 직접 전달함<button>과 <div> 같은 빌트인 컴포넌트는 onClick과 같은 브라우저 이벤트 이름만을 지원하는 한펴, 사용자 정의 컴포넌트에서는 이벤트 핸들러 prop의 이름을 원하는 대로 명명할 수 있음. on으로 시작하여 대문자 영문으로 이어짐.📍 컴포넌트가 여러 상호작용을 지원한다면 이벤트 핸들러 prop을 애플리케이션에 특화시켜 명명할 수 있다.
export default function App() {
return (
<Toolbar
onPlayMovie={() => alert('Playing!')}
onUploadImage={() => alert('Uploading!')}
/>
);
}
function Toolbar({ onPlayMovie, onUploadImage }) {
return (
<div>
<Button onClick={onPlayMovie}>
Play Movie
</Button>
<Button onClick={onUploadImage}>
Upload Image
</Button>
</div>
);
}
function Button({ onClick, children }) {
return (
<button onClick={onClick}>
{children}
</button>
);
}
Toolbar컴포넌트가 onPlayMovie와 onUploadImage 이벤트 핸들러를 받음.onPlayMovie와 같이 prop이름을 애플리케이션별 상호작용에 기반하여 명명한다면 나중에 이를 어떻게 이용하게 될지에 대한 유연성을 제공할 수 있음. 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이 뒤이어 실행됨. 따라서 두 개의 메시지가 표현됨.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>
);
}
버튼 클릭 시 실행되는 과정
1. React가 에 전달된 onClick 핸들러를 호출
2. Button에 정의된 해당 핸들러는 다음을 수행함
e.stopPropagation() 을 호출하여 이벤트가 더 이상 bubbling 되지 않도록 방지onClick 함수를 호출Toolbar 컴포넌트에서 정의된 위 함수가 버튼의 alert를 표시<form>의 제출 이벤트가 그 내부의 버튼을 클릭하면 페이지 전체를 리로드하는 것이 있음.export default function Signup() {
return (
<form onSubmit={() => alert('Submitting!')}>
<input />
<button>Send</button>
</form>
);
}
e.preventDefault()를 이벤트 오브젝트에서 호출할 수 있음export default function Signup() {
return (
<form onSubmit={e => {
e.preventDefault();
alert('Submitting!');
}}>
<input />
<button>Send</button>
</form>
);
}
e.stopPropagation() : 이벤트 핸들러가 상위 태그에서 실행되지 않도록 멈춤e.preventDefault() : 기본 브라우저 동작을 가진 일부 이벤트가 해당 기본 동작을 실행하지 않도록 방지