React 엘리먼트에서 이벤트를 처리하는 방식은 DOM 엘리먼트에서 이벤트를 처리하는 방식과 매우 유사하지만 몇가지 차이점이 있습니다.
- React의 이벤트는 소문자 대신 캐멀 케이스(camelCase)를 사용합니다.
- JSX를 사용하여 문자열이 아닌 함수로 이벤트 핸들러를 전달합니다.
onClick={}
- React에서는 false를 반환해도 기본 동작을 방지할 수 없습니다. 따라서, 반드시 preventDefault를 명시적으로 호출해야 합니다.
//핸들러
const showMsg = () => {
alert('안녕!')
}
//사용
<button onClick={showMsg}></button>
만약, 인자로 받는 함수가 있는 경우 아래와 같이 작성해, 인자를 전달하면서 함수를 실행할 수 있습니다.
const showMsg = (msg) => {
alert(msg)
}
<button onClick={() => showMsg('안녕!')}></button>
onChange
를 사용하면, input 태그에서 내부 내용이 바뀔 때 실행될 함수를 지정할 수 있습니다.
function ChildComp() {
const [num, setNum] = useState(0)
const changeHandler = (e) => {
setNum(e.target.value)
}
return (
<>
<input onChange={changeHandler} />
<div>{num}</div>
</>
)
}
//React에서의 기본동작방지
function Form() {
function handleSubmit(e) {
e.preventDefault();
console.log('You clicked submit.');
}
return (
<form onSubmit={handleSubmit}>
<button type="submit">Submit</button>
</form>
);
}
합성이벤트
- React는 UI라이브러리로, 당연히 DOM의 기본적인 이벤트들을 다룰 수 있어야합니다.
- 그렇기 때문에 웹표진인 Event인터페인스를 래핑하고 있습니다. 이를 합성이벤트라고 합니다
App.js
import Banner from './components/Banner';
function App() {
return (
<div>
<Banner />
</div>
)
}
export default App;
Banner.js
const Banner = () => {
const [show, setShow] = useState(true)
function showAlert() {
alert('10% 할인 쿠폰에 당첨되었습니다.')
}
function closeBanner(e) {
e.stopPropagation() //✅
setShow(false)
}
return (
show && <div
onClick={showAlert}
style={{
backgroundColor: "orange",
fontWeight: "bold",
height: "50px",
display: "flex",
justifyContent: "space-around",
alignItems: "center",
}}
>
이 곳을 클릭해서 쿠폰을 받아가세요.
<button onClick={closeBanner}>닫기</button>
</div>
);
};
export default Banner;
이벤트 버블링으로 인해 닫기버튼을 누르면 alert창이 뜬 후 배너가 사라지는 이슈가 발생하게 됩니다.따라서 closeBanner
함수에 e.stopPropagation()
처리를 헤줘야합니다.
그런데 이벤트 버블링에 의하면 closeBanner가 먼저 실행이 된 후 showAlert이 실행되어야 하는데 반대로 showAlert이 실행된 후 closeBanner되는 것을 확인할 수 있습니다.
이는 setShow가 비동기로 처리되는 함수이기 때문입니다. 따라서 closeBanner가 먼저 호출되더라도 showAlert가 먼저 실행되게 되는 것입니다.
import React, { useState } from 'react'
function Login() {
const [inputValue, setInputValue] = useState({
id: '',
pwd: '',
})
const doLogin = () => {
alert(`${inputValue.id} 로그인 완료!`)
}
const changeHandler = (e) => {
const { name, value } = e.target
setInputValue({
...inputValue,
[name]: value,
})
}
return (
<div>
<input
placeholder="아이디를 입력하세요"
value={inputValue.id}
name="id"
onChange={changeHandler}
/>
<input
placeholder="비밀번호를 입력하세요"
type="password"
value={inputValue.pwd}
name="pwd"
onChange={changeHandler}
/>
<button onClick={doLogin}>로그인</button>
</div>
)
}
export default Login
import React, { useState, useRef } from 'react'
function LoginRef() {
const [inputValue, setInputValue] = useState()
const inputRef = useRef()
const changeHandler = () => {
setInputValue(`${inputRef.current.value}`)
}
return (
<div>
<input
placeholder="검색어를 입력하세요"
ref={inputRef}
onChange={changeHandler}
/>
{inputValue}
</div>
)
}
export default LoginRef