DOM의 이벤트 처리 방식과 유사하며 몇 가지 문법 차이가 있다.
React에서 이벤트는 소문자 대신 카멜 케이스(camelCase) 를 사용한다.
JSX를 사용하여 문자열이 아닌 함수로 이벤트 처리 함수(이벤트 핸들러)를 전달한다.
예를 들어 HTML에서 이벤트 처리 방식이 아래와 같다면,
<button onclick="handleEvent()">Event</button>
React의 이벤트 처리 방식은 아래와 같다.
<button onClick={handleEvent}>Event</button>
<input>
<textarea>
<select>
와 같은 폼(Form) 엘리먼트는 사용자의 입력값을 제어하는 데 사용된다.
React에서는 이러한 변경될 수 있는 입력값을 일반적으로 컴포넌트의 state로 관리하고 업데이트한다.
onChange
이벤트가 발생하면 e.target.value
를 통해 이벤트 객체에 담겨있는 input
값을 읽어올 수 있다.
컴포넌트 return
문 안의 input
태그에 value
와 onChange
를 작성하고,
onChange
는 input
의 텍스트가 바뀔 때마다 발생하는 이벤트로, 이벤트가 발생하면 handleChange
함수가 작동하며, 이벤트 객체에 담긴 input
값을 setState
를 통해 새로운 state 로 갱신한다.
아래는 onChange
를 이용한 예시코드이다.
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value);
}
return (
<div>
<input type="text" value={name} onChange={handleChange}></input>
<h1>{name}</h1>
</div>
)
};
사용자가 클릭이라는 행동을 했을 때 발생하는 이벤트로, 주로 사용자의 행동에 따라 애플리케이션이 반응해야 할 때 자주 사용된다.(버튼, <a>
tag 를 통한 링크 이동 등)
아래는 위의 onChange
예시에 버튼을 추가하여 버튼 클릭 시 <input>
tag 에 입력한 이름이alert
을 통해 알림 창이 팝업 되도록 추가 구현한 코드이다.
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value);
}
return (
<div>
<input type="text" value={name} onChange={handleChange}></input>
<button onClick={alert(name)}>Button</button> // 추가된 코드
<h1>{name}</h1>
</div>
);
};
위와 같이 onClick
이벤트에 alert(name)
함수를 바로 호출하면 컴포넌트가 렌더링 될 때 함수 자체가 아닌 함수 호출의 결과가 onClick
에 적용된다.
때문에 버튼을 클릭할 때가 아닌, 컴포넌트가 렌더링 될 때에 alert
이 실행되고, 그 결과인 undefined
(return 값 x) 가 onClick
에 적용되어 클릭했을 때 아무런 결과도 일어나지 않는다.
따라서, onClick
이벤트에 함수를 전달할 때는 함수를 호출하는 것이 아니라 아래와 같이 리턴문 안에서 함수를 정의하거나 리턴문 외부에서 함수를 정의 후 이벤트에 함수 자체를 전달해야 한다.
단, 두 가지 방법 모두 arrow function 을 사용하여 함수를 정의하여야 해당 컴포넌트가 가진 state에 함수들이 접근할 수 있다.
// 리턴문 안에서 함수 정의
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value);
};
return (
<div className="App">
<h1>Event handler practice</h1>
<input type="text" value={name} onChange={handleChange}></input>
<button onClick={() => alert(name)}>Button</button> // 수정된 코드
<h3>{name}</h3>
</div>
);
}
// 리턴문 외부에서 함수를 정의 후 이벤트에 함수 전달
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value);
};
const handleClick = () => {
alert(name);
}; // 추가된 코드
return (
<div className="App">
<h1>Event handler practice</h1>
<input type="text" value={name} onChange={handleChange}></input>
<button onClick={handleClick}>Button</button> // 수정된 코드
<h3>{name}</h3>
</div>
);
}
최종 코드 실행 시(css 별도) 아래와 같이 화면을 출력한다.
<select>
Q . <select>
tag 는 사용자가 drop down 목록을 열어 그중 한 가지 옵션을 선택하면, 선택된 옵션이 state 변수에 갱신됩니다. useState
가 어떠한 상태를 갱신하도록 설정되어 있는지 확인한 뒤, 주석에 따라 <select>
tag 가 정상적으로 작동하도록 코드를 완성하세요.
function SelectExample() {
const [choice, setChoice] = useState("apple");
const fruits = ["apple", "orange", "pineapple", "strawberry", "grape"];
const options = fruits.map((fruit) => {
return <option value={fruit}>{fruit}</option>;
});
console.log(choice);
const handleFruit = (event) => {
//TODO : select tag 가 정상적으로 작동하도록 코드를 완성하세요.
setChoice(event.target.value);
};
return (
<div className="App">
<select onChange={handleFruit}>{options}</select>
<h3>You choose "{choice}"</h3>
</div>
);
}
<pop up>
Q . Pop up
역시 Pop up
의 open
과 close
를 state 를 통해 관리할 수 있습니다.
이 예제 또한 useState
를 확인하여 버튼 클릭에 따라 Pop up
이 open/close 되도록 코드를 완성하세요.
function App() {
const [showPopup, setShowPopup] = useState(false);
const togglePopup = () => {
// Pop up 의 open/close 상태에 따라
// 현재 state 가 업데이트 되도록 함수를 완성하세요.
if(showPopup === false){
setShowPopup(true);
}
else{
setShowPopup(false);
}
};
return (
<div className="App">
<h1>Fix me to open Pop Up</h1>
{/* 버튼을 클릭했을 때 Pop up 의 open/close 가 작동하도록
button tag를 완성하세요. */}
<button className="open" onClick={togglePopup}>Open me</button>
{showPopup ? (
<div className="popup">
<div className="popup_inner">
<h2>Success!</h2>
<button className="close" onClick={togglePopup}>
Close me
</button>
</div>
</div>
) : null}
</div>
);
}
Reference: 코드스테이츠