Open beecomci opened 3 years ago
React 적용 가이드 - React 작동 방법 글은 React 17 이전 버전에 대한 내용이 대부분 17 버전부터는 Event Pooling 방식 미사용 + 이벤트가 등록되는 엘리먼트가 document에서 root로 변경된 것을 제외하고 기본적인 이해만 돕고자 Event Delegation과 React syntheticEvent 객체만 정리함
추가 참고 문서
버블링
이며, 캡쳐링
방식으로 변경 가능event.target
을 이용하면 실제 어디서 이벤트가 발생했는지 알 수 있음캡쳐링 -> event.target 노드 -> 버블링
순서대로 발생<div class="one">
one
<div class="two">
two
<div class="three">
three
</div>
</div>
</div>
var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
div.addEventListener('click', logEvent);
});
function logEvent(event) {
console.log(event.currentTarget.className);
}
var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
// addEventListener API에서 옵션 객체에 capture:true 설정 -> 해당 이벤트 감지하기 위해 버블링과 반대 방향으로 탐색
div.addEventListener('click', logEvent, { capture: true });
});
function logEvent(event) {
console.log(event.currentTarget.className);
}
event.stopPropagation()
은 해당 이벤트가 전파되는 것을 막음function Form() {
function handleSubmit(e) {
e.preventDefault();
console.log('You clicked submit.');
}
return (
<form onSubmit={handleSubmit}>
<button type="submit">Submit</button>
</form>
);
}
e
는 SyntheticEvent(합성 이벤트) addEventListener
를 호출할 필요 없음, 대신 엘리먼트가 처음 렌더링될 때 리스너 제공하면 됨class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// 1. 콜백에서 `this`가 작동하려면 아래와 같이 바인딩 해주어야 합니다.
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
// 2. this가 handleClick 내에서 바인딩 되도록
render() {
return (
<button onClick={() => this.handleClick()}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
/*render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}*/
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
bind
호출this.handleClick
메서드를 바인딩하지 않고 onClick에 전달하면 함수가 실제로 호출될 때 this는 undefined가 됨arrow function
사용<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
React event handling #
React event delegation
React v16 이전 : 타입별 이벤트를 모두 document에 하나씩 걸고 어디서든 이벤트가 발생하면 이벤트를 찾기 위해 document까지 타고 올라가고 등록된 이벤트 발견, document에서 등록된 이벤트를 찾아서 실행시킴
React v17: document가 아니라 root element 위치로 바뀜, 여러개의 react 버전을 섞어서 사용하는걸 지원하기 위해 변경됨, react 외에 다른 라이브러리와 사용하는 경우 거기서 발생한 이벤트를 정지시킨다던가 하는 이슈가 있었음
실제 DOM element의 event handling과 비슷
event callback 함수에 전달되는 event 객체는 React에서 합성한 event 객체(syntheticEvent) -> 실제 native 이벤트는 아님(실제 브라우저가 발생한 이벤트)
실제 native event 객체에 접근하기 위해서는
e.nativeEvent
사용 (그냥 syntheticEvent 객체가 모던 브라우저에서 사용하는 이벤트 객체와 비슷하기 때문에 사용하면 됨)차이
onClick
string
이 아닌 실제function
전달return false
사용 불가e.preventDefault()
@05-event-handling/preventDefault
메모리 누수를 위한
addEventListener() / removeEventListener()
사용할 필요 없음React의 syntheticEvent #
Event pooling #
event.persist()
호출event.persist()
event pooling 방식이 아니어서event.persist()
호출의미가 없음.참고: React 적용 가이드 - React 작동 방법