클릭 시 중첩된 React 구성 요소에서 이벤트가 버블링되는 것을 방지하려면 어떻게 해야 합니까?
여기 기본 컴포넌트가 있습니다.둘 다<ul>
그리고.<li>
onClick 기능이 있습니다.onClick만 원하는 경우<li>
발사하는 것이 아니라<ul>
어떻게 하면 좋을까요?
e.proventDefault(), e.stopPropagation()을 가지고 놀았지만 소용이 없었습니다.
class List extends React.Component {
constructor(props) {
super(props);
}
handleClick() {
// do something
}
render() {
return (
<ul
onClick={(e) => {
console.log('parent');
this.handleClick();
}}
>
<li
onClick={(e) => {
console.log('child');
// prevent default? prevent propagation?
this.handleClick();
}}
>
</li>
</ul>
)
}
}
// => parent
// => child
저도 같은 문제가 있었어요.stopPropagation이 작동했습니다.목록 항목을 다음과 같이 다른 구성요소로 분할합니다.
class List extends React.Component {
handleClick = e => {
// do something
}
render() {
return (
<ul onClick={this.handleClick}>
<ListItem onClick={this.handleClick}>Item</ListItem>
</ul>
)
}
}
class ListItem extends React.Component {
handleClick = e => {
e.stopPropagation(); // <------ Here is the magic
this.props.onClick();
}
render() {
return (
<li onClick={this.handleClick}>
{this.props.children}
</li>
)
}
}
React는 문서의 단일 이벤트 리스너와 함께 이벤트 위임을 사용합니다. 즉, 이 예에서는 '클릭'과 같이 버블이 발생하는 이벤트에 대해 전파를 중지할 수 없습니다. 실제 이벤트는 React에서 해당 이벤트와 상호 작용할 때 이미 전파되었습니다. stopReact는 Synt의 전파를 처리하므로 React의 합성 이벤트에 대한 전파가 가능합니다.내부 hetic 이벤트.
stopPropagation: function(e){
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
}
DOM 이벤트 순서: CAPTION VS BUBB링
이벤트가 전파되는 방법에는 두 가지 단계가 있습니다.이것들은 "포착"과 "거품"이라고 불립니다.
| | / \
---------------| |----------------- ---------------| |-----------------
| element1 | | | | element1 | | |
| -----------| |----------- | | -----------| |----------- |
| |element2 \ / | | | |element2 | | | |
| ------------------------- | | ------------------------- |
| Event CAPTURING | | Event BUBBLING |
----------------------------------- -----------------------------------
캡처 단계가 먼저 발생하고 그 다음 거품이 튀는 단계가 이어집니다.일반 DOM API를 사용하여 이벤트를 등록하면 기본적으로 이벤트가 버블링 스테이지의 일부가 되지만 이벤트 생성 시 지정할 수 있습니다.
// CAPTURING event
button.addEventListener('click', handleClick, true)
// BUBBLING events
button.addEventListener('click', handleClick, false)
button.addEventListener('click', handleClick)
React에서는 버블링 이벤트도 기본적으로 사용됩니다.
// handleClick is a BUBBLING (synthetic) event
<button onClick={handleClick}></button>
// handleClick is a CAPTURING (synthetic) event
<button onClickCapture={handleClick}></button>
핸들 내부를 살펴보겠습니다.클릭 콜백(반응):
function handleClick(e) {
// This will prevent any synthetic events from firing after this one
e.stopPropagation()
}
function handleClick(e) {
// This will set e.defaultPrevented to true
// (for all synthetic events firing after this one)
e.preventDefault()
}
여기서 본 적이 없는 대안
모든 이벤트에서 e.proventDefault()를 호출하면 이벤트가 이미 처리되었는지 확인하고 다시 처리되지 않도록 할 수 있습니다.
handleEvent(e) {
if (e.defaultPrevented) return // Exits here if event has been handled
e.preventDefault()
// Perform whatever you need to here.
}
모의 이벤트와 네이티브이벤트의 차이에 대해서는, React 메뉴얼을 참조해 주세요.https://reactjs.org/docs/events.html
이렇게 하면 클릭 이벤트가 다음 컴포넌트로 넘어가는 것을 방지하고 자신의 기능을 호출할 수 있습니다.
<Button onClick={(e)=> {e.stopPropagation(); yourFunction(someParam)}}>Delete</Button>
100% 이상적이지는 않지만 물려주기에는 너무 고통스럽거나 둘 중 하나일 경우props
children -> children 패션 또는 작성Context.Provider
/Context.Consumer
이 목적을 위해서만)를 실행하고 있는 다른 라이브러리의 핸들러를 사용하고 있는 경우, 다음의 조작도 실행할 수 있습니다.
function myHandler(e) {
e.persist();
e.nativeEvent.stopImmediatePropagation();
e.stopPropagation();
}
제가 알기로는event.persist
method는 오브젝트가 React의 오브젝트로 즉시 되돌려지는 것을 방지합니다.SyntheticEvent
수영장이요. 그래서 그 때문에event
React에 전달된 것은 실제로 당신이 손을 뻗을 때쯤에는 존재하지 않습니다.이러한 현상은 손자 손녀들에게서 발생합니다.처음 부모를 체크함으로써 내부적으로 대처하는 방법 때문에 발생합니다.SyntheticEvent
핸들러(특히 부모에게 콜백이 있는 경우)
당신이 전화하지 않는 한persist
다음과 같은 이벤트를 계속 생성하기 위해 중요한 메모리를 생성하는 무언가에 대해onMouseMove
(그리고 당신은 할머니의 쿠키와 같은 쿠키클릭 게임을 만들지는 않을 것입니다)완벽하게 잘 될 거예요!
주의: GitHub에서 가끔 읽는 것부터, 향후의 React 버전에 주의해 주세요.그것은, 컴파일러/트랜스필러로 React 코드를 접는 것을 목표로 하고 있는 것처럼 보이기 때문입니다.
부모 요소의 액션이 아닌 네스트된 요소의 액션을 실행하는 경우 부모 요소의 액션핸들러에서 타깃 유형을 체크하고 그에 따라 액션을 수행합니다.즉, 타겟이 네스트된 요소일 경우 아무것도 하지 않습니다.그렇지 않으면 양쪽 핸들러가 호출됩니다.
// Handler of the parent element. Let's assume the nested element is a checkbox
function handleSingleSelection(e) {
if(e.target.type !== 'checkbox') {
// We do not do anything from the
// parent handler if the target is a checkbox ( our nested element)
// Note that the target will always be the nested element
dispatch(lineSelectionSingle({ line }))
}
}
나는 그것을 얻는데 어려움을 겪었다.event.stopPropagation()
일해.이 경우에도 클릭 핸들러 기능의 맨 위로 이동해 보십시오.이것이 이벤트의 거품을 막기 위해서 필요한 것입니다.함수 예:
toggleFilter(e) {
e.stopPropagation(); // If moved to the end of the function, will not work
let target = e.target;
let i = 10; // Sanity breaker
while(true) {
if (--i === 0) { return; }
if (target.classList.contains("filter")) {
target.classList.toggle("active");
break;
}
target = target.parentNode;
}
}
이벤트 대상을 확인함으로써 이벤트 버블을 방지할 수 있습니다.
예를 들어 클릭 이벤트에 대한 핸들러가 있는 div 요소에 입력이 중첩되어 있고 이를 처리하지 않으려면 입력을 클릭할 때 그냥 통과하면 됩니다.event.target
핸들러에 삽입하여 대상 속성에 따라 핸들러를 실행해야 합니다.
예를 들어,if (target.localName === "input") { return}
.
즉, 핸들러의 실행을 회피하는 방법입니다.
이 문제에 대한 또 다른 접근법은 자녀에 대해 onMouseEnter 및 onMouseLeave 이벤트를 설정하는 것입니다.(< li > 태그) 마우스가 아이 주변을 맴돌 때마다 특정 상태를 설정하여 부모가 onClick 함수 콘텐츠 실행을 정지할 수 있습니다.예를 들어 다음과 같습니다.
class List extends React.Component {
constructor(props) {
super(props)
this.state.overLi = false
}
handleClick() {
// do something
}
render() {
return (
<ul
onClick={(e) => {
if (!this.state.overLi) {
console.log("parent")
this.handleClick()
}
}}
>
<li
onClick={(e) => {
console.log("child")
// prevent default? prevent propagation?
this.handleClick()
}}
onMouseEnter={() =>
this.setState({
overLi: true,
})
}
onMouseLeave={() =>
this.setState({
overLi: false,
})}
></li>
</ul>
)
}
}
많이 검색했지만 e.stopPropagation()을 사용하여 컨텍스트에 맞는 솔루션을 구현하지 못했습니다.
이 새로운 방법은 훨씬 더 간단하며 시간을 절약할 수 있습니다!원래 클릭 핸들러에 이벤트를 전달하고 호출만 하면 됩니다.preventDefault();
.
clickHandler(e){
e.preventDefault();
//Your functionality here
}
언급URL : https://stackoverflow.com/questions/38619981/how-can-i-prevent-event-bubbling-in-nested-react-components-on-click
'programing' 카테고리의 다른 글
Woocommerce 3에서 관련 제품 제목 이름 변경 (0) | 2023.03.04 |
---|---|
크로스 오리진(CORS) 오류 검출 방법Javascript의 XMLHttpRequest()에 대한 기타 오류 유형 (0) | 2023.03.04 |
Oracle SQL의 테이블에 대한 모든 제약 조건 이름 표시 (0) | 2023.03.04 |
$viewContentLoaded가 실행되지 않습니다. (0) | 2023.03.04 |
AngularJS: URL에서 쿼리 파라미터를 클리어하려면 어떻게 해야 합니까? (0) | 2023.03.04 |