
React는 HTML의 이벤트 처리 방식을 기반으로 하지만, 약간의 차이가 있다.
onclick)이다.<button onclick="activeEvent();">
Event Button
</button>onClick, onChange, onMouseEnter<button onclick={activeEvent}>
Event Button
</button>여기서 생길 수 있는 의문!
리액트에서는 {} 이렇게 묶어서 사용한다는 것은 알겠는데 () 괄호는 왜 사용하지 않을까?
그 이유 :
onClick={activeEvent}: 함수 참조를 전달한다. 클릭 이벤트가 발생했을 때 React가 해당 함수를 실행한다.onClick={activeEvent()}: 함수가 즉시 실행된 결과를 전달한다. 클릭과 상관없이 컴포넌트 렌더링 시점에 함수가 실행되므로 잘못된 동작을 유발할 수 있다.React는 이벤트에 함수를 호출하는 HTML과 달리 이벤트에 함수를 정의한다.
왜냐하면 React는 렌더링 할 때 모든 컴포넌트의 함수를 실행시켜 컴포넌트 렌더링 시 이벤트가 발생하지 않아도 해당 이벤트 함수가 실행되기 때문이다.
함수명만 작성
<button onClick={이벤트함수명}>Event Button</button>
화살표 함수로 작성
<button onClick={()=>{이벤트함수명()}}>Event Button</button>
이를 방지하기 위해 함수명만 작성하거나, 화살표 함수로 이벤트에 함수를 정의해 이벤트가 발생했을 때만 작성한 이벤트 함수가 실행되도록 한다. 위의 두 예제는 같은 기능을 한다.
```jsx
<button onClick={handleClick}>클릭하세요</button> // 올바른 예
``````jsx
function handleClick() {
console.log('Button clicked!');
}
<button onClick={handleClick}>클릭</button>
``````jsx
function MyButton({ onClick }) {
return <button onClick={onClick}>내 버튼</button>;
}
<MyButton onClick={handleClick} />
```
웹 브라우저의 이벤트 시스템 :
웹 브라우저가 자체적으로 가지고 있는 이벤트 처리 시스템을 말한다.
사용자의 클릭, 키보드 입력, 마우스 이동 등의 상호작용으로 인해 발생하는 이벤트를 처리한다.
이 웹 브라우저의 이벤트 시스템은 브라우저 별로 다르다. 그렇기 때문에 각 브라우저 별로 이벤트를 다르게 지정해야 하는데 React는 이런 부분에 편의성을 위해 SyntheticEvent를 제공한다.
이어서 ⬇️
React는 합성 이벤트(SyntheticEvent)라는 래퍼(Wrapper) 객체를 사용해, 브라우저의 nativeEvnet 이벤트를 감싼다.
이를 통해 모든 브라우저에서 일관된 이벤트 처리가 가능하다.
(Wrapper란 - Wrapper객체란 기본 기능을 감싸는 새로운 기능 )
function handleClick(e) {
console.log(e.type); // 'click'
console.log(e.nativeEvent); // 브라우저의 원래 이벤트 객체
}
<button onClick={handleClick}>클릭</button>자세한 이벤트 종류는 React 공식 문서를 참고!
여기까지의 정리
React는 nativeEvnet라는 브라우저의 고유 이벤트를 Wrapping한 SyntheticEvent 객체를 통해 이벤트를 처리한다. 그리고 SyntheticEvent 객체는 event 또는 e라는 축약 형태로 작성하고, 이 객체가 제공하는 다양한 속성과 메서드를 참조한다.
SyntheticEvent 내에 포함된 원래의 브라우저 이벤트를 가리킨다.
주의 : nativeEvnet는 SyntheticEvent 내에 포함된 원래의 브라우저 이벤트 이지만 SyntheticEvent가 브라우저의 nativeEvnet와 완벽하게 대응되는 것은 아니다.
예를들어 onMouseLeave 이벤트의 event.nativeEvnet는 mouseout 이벤트를 가리킨다.
브라우저의 고유 이벤트인 nativeEvnet를 확인하고 싶다면 event.nativeEvnet attribute(속성)을 이용하면 된다.
export default function SyntheticEventAttr() {
const checkType = (e) => {
console.log('e.type:', e.type);
};
return (
<>
<button onClick={checkType}>click</button>
<input type='text' onChange={checkType} />
</>
);
}export default function SyntheticEventAttr() {
const checkType = (e) => {
console.log("e.type:", e.type);
};
const checkTargete = (e) => {
console.log("e.target:", e.target);
};
const checkCurrentTarget = (e) => {
console.log("e.currentTarget:", e.currentTarget);
};
return (
<>
<button onClick={checkType}>click</button>
<input type="text" onChange={checkType} />
<h3>e.target</h3>
<button onClick={checkTargete}>
<span>click</span>
</button>
<h3>e.currentTarget</h3>
<button onClick={checkCurrentTarget}>
<span>click</span>
</button>
</>
);
}this를 사용해 이벤트 핸들러에 접근해야 한다.class App extends React.Component {
handleClick() {
console.log(this);
}
render() {
return <button onClick={this.handleClick.bind(this)}>클릭</button>;
}
}
bind 사용:bind해야 한다.constructor() {
super();
this.handleClick = this.handleClick.bind(this);
}
this를 자동으로 바인딩한다.handleClick = () => {
console.log(this);
};
React의 함수형 컴포넌트는 간결한 이벤트 처리 방식을 제공한다.
const handleClick = () => {
console.log('클릭!');
};
<button onClick={handleClick}>클릭</button>
const handleClick = (msg) => {
console.log(msg);
};
<button onClick={() => handleClick('안녕하세요')}>클릭</button>