
제목: React – 테이블 내에서 레이블 클릭의 전파 방지
이 블로그 포스트에서는 React 애플리케이션에서 테이블 내 레이블 클릭 시 이벤트 전파를 방지하는 방법을 살펴보겠습니다. 구체적으로, 일반적인 이벤트 버블링이 발생하여 체크박스 클릭 핸들러가 다른 순서로 트리거되는 문제를 해결할 것입니다. 체크박스 클릭 이벤트가 상위 요소로 버블링되지 않도록 여러 가지 해결책을 제공할 것입니다.
문제 이해하기
문제는 htmlFor 속성을 사용하여 레이블을 체크박스와 연결했을 때 발생합니다. 체크박스 자체는 event.stopPropagation()과 함께 예상대로 작동하지만, 레이블은 자체적인 클릭 핸들러가 없어 이벤트 전파를 중단할 수 없습니다.
해결책 1: 레이블에 별도의 클릭 핸들러 추가
이 문제를 해결하기 위해 레이블에 event.stopPropagation()을 포함한 별도의 클릭 핸들러를 추가할 수 있습니다. 이를 통해 레이블 클릭 시 이벤트 버블링을 방지할 수 있습니다. 다음은 예시입니다:
var Hello = React.createClass({
func1(e){
console.log('tr이 클릭되었습니다')
},
func2(e){
console.log('td가 클릭되었습니다')
},
func3(e){
e.stopPropagation();
console.log('체크박스가 클릭되었습니다')
},
stopLabelPropagation(e) {
e.stopPropagation();
},
render: function() {
return <table>
<tbody>
<tr onClick={this.func1}>
<td onClick={this.func2}>
<input id="thing" type="checkbox" onClick={this.func3} />
<label htmlFor="thing" onClick={ this.stopLabelPropagation }>체크박스용 레이블</label>
</td>
</tr>
</tbody>
</table>;
}
});
ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
해결책 2: 레이블을 Span으로 래핑하고 StopPropagation 추가
다른 해결책으로는 레이블을 Span으로 래핑하고 Span의 onClick 이벤트에 event.stopPropagation()을 추가하는 것입니다. 이를 통해 레이블 클릭 시 이벤트 전파를 방지할 수 있습니다. 다음은 예시입니다:
var Hello = React.createClass({
func1(e){
console.log('tr이 클릭되었습니다')
},
func2(e){
console.log('td가 클릭되었습니다')
},
func3(e){
e.stopPropagation();
console.log('체크박스가 클릭되었습니다')
},
render: function() {
return <table>
<tbody>
<tr onClick={this.func1}>
<td onClick={this.func2}>
<span onClick={evt => evt.stopPropagation() }>
<input id="thing" type="checkbox" onClick={this.func3} />
<label htmlFor="thing">체크박스용 레이블</label>
</span>
</td>
</tr>
</tbody>
</table>;
}
});
ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
해결책 3: 레이블에 onClick 이벤트 추가
또 다른 해결책은 레이블 자체에 onClick 이벤트를 추가하고, 체크박스 클릭 핸들러와 동일한 함수에 바인딩하는 것입니다. 이를 통해 이벤트 전파가 방지되고, 체크박스 클릭 이벤트가 마지막으로 수신되도록 할 수 있습니다. 다음은 예시입니다:
var Hello = React.createClass({
func1(e){
console.log('tr이 클릭되었습니다')
},
func2(e){
console.log('td가 클릭되었습니다')
},
func3(e){
e.stopPropagation();
console.log('체크박스가 클릭되었습니다')
},
render: function() {
return <table>
<tbody>
<tr onClick={this.func1}>
<td onClick={this.func2}>
<input id="thing" type="checkbox" onClick={this.func3} />
<label htmlFor="thing" onClick={this.func3}>체크박스용 레이블</label>
</td>
</tr>
</tbody>
</table>;
}
});
ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
이러한 해결책 중 하나를 구현함으로써, React 애플리케이션에서 테이블 내의 레이블 클릭 시 이벤트 전파를 효과적으로 방지할 수 있습니다.