深入了解React中的合成事件
1 事件三個(gè)階段 捕獲、目標(biāo)、處理 (具體百度,后面有空補(bǔ)全)
2 示例
import React from "react";
class Test extends React.Component {
parentRef;
childRef;
constructor(props) {
super(props);
this.parentRef = React.createRef();
this.childRef = React.createRef();
}
componentDidMount() {
document.addEventListener(
"click",
() => {
console.log(`document原生事件捕獲`);
},
true
);
document.addEventListener("click", () => {
console.log(`document原生事件冒泡`);
});
this.parentRef.current.addEventListener(
"click",
() => {
console.log(`父元素原生事件捕獲`);
},
true
);
this.parentRef.current.addEventListener("click", () => {
console.log(`父元素原生事件冒泡`);
});
this.childRef.current.addEventListener(
"click",
() => {
console.log(`子元素原生事件捕獲`);
},
true
);
this.childRef.current.addEventListener("click", () => {
console.log(`子元素原生事件冒泡`);
});
}
handleParentBubble = () => {
console.log(`父元素React事件冒泡`);
};
handleChildBubble = (e) => {
console.log(`子元素React事件冒泡`);
};
handleParentCapture = () => {
console.log(`父元素React事件捕獲`);
};
handleChileCapture = () => {
console.log(`子元素React事件捕獲`);
};
render() {
return (
<div
ref={this.parentRef}
onClick={this.handleParentBubble}
onClickCapture={this.handleParentCapture}
>
<div
ref={this.childRef}
onClick={this.handleChildBubble}
onClickCapture={this.handleChileCapture}
>
事件處理測(cè)試
</div>
</div>
);
}
}
export default Test;執(zhí)行順序

只留子元素修改代碼
import React from "react";
class Test extends React.Component {
parentRef;
childRef;
constructor(props) {
super(props);
this.parentRef = React.createRef();
this.childRef = React.createRef();
}
componentDidMount() {
document.addEventListener(
"click",
() => {
console.log(`document原生事件捕獲`);
},
true
);
document.addEventListener("click", () => {
console.log(`document原生事件冒泡`);
});
// this.parentRef.current.addEventListener(
// "click",
// () => {
// console.log(`父元素原生事件捕獲`);
// },
// true
// );
// this.parentRef.current.addEventListener("click", () => {
// console.log(`父元素原生事件冒泡`);
// });
this.childRef.current.addEventListener(
"click",
() => {
console.log(`子元素原生事件捕獲`);
},
true
);
this.childRef.current.addEventListener("click", () => {
console.log(`子元素原生事件冒泡`);
});
}
// handleParentBubble = () => {
// console.log(`父元素React事件冒泡`);
// };
handleChildBubble = (e) => {
console.log(`子元素React事件冒泡`);
};
// handleParentCapture = () => {
// console.log(`父元素React事件捕獲`);
// };
handleChileCapture = () => {
console.log(`子元素React事件捕獲`);
};
render() {
return (
<div
ref={this.childRef}
onClick={this.handleChildBubble}
onClickCapture={this.handleChileCapture}
>
事件處理測(cè)試
</div>
);
return (
<div
ref={this.parentRef}
onClick={this.handleParentBubble}
onClickCapture={this.handleParentCapture}
>
<div
ref={this.childRef}
onClick={this.handleChildBubble}
onClickCapture={this.handleChileCapture}
>
事件處理測(cè)試
</div>
</div>
);
}
}
export default Test;
document原生事件捕獲--》子元素React事件捕獲--》子元素原生事件捕獲--》子元素原生事件冒泡--》子元素React事件冒泡--》document原生事件冒泡
從這個(gè)執(zhí)行順序來看,react事件捕獲執(zhí)行比原生事件捕獲早,但是原生事件冒泡執(zhí)行比react事件冒泡快。
所有的react捕獲事件執(zhí)行完畢之后才會(huì)去執(zhí)行原生的捕獲事件(document原生事件捕獲最先執(zhí)行)
3 子元素阻止react事件冒泡
e.stopPropagation();
import React from "react";
class Test extends React.Component {
parentRef;
childRef;
constructor(props) {
super(props);
this.parentRef = React.createRef();
this.childRef = React.createRef();
}
componentDidMount() {
document.addEventListener(
"click",
() => {
console.log(`document原生事件捕獲`);
},
true
);
document.addEventListener("click", () => {
console.log(`document原生事件冒泡`);
});
this.parentRef.current.addEventListener(
"click",
() => {
console.log(`父元素原生事件捕獲`);
},
true
);
this.parentRef.current.addEventListener("click", () => {
console.log(`父元素原生事件冒泡`);
});
this.childRef.current.addEventListener(
"click",
() => {
console.log(`子元素原生事件捕獲`);
},
true
);
this.childRef.current.addEventListener("click", () => {
console.log(`子元素原生事件冒泡`);
});
}
handleParentBubble = () => {
console.log(`父元素React事件冒泡`);
};
handleChildBubble = (e) => {
e.stopPropagation();
console.log(`子元素React事件冒泡`);
};
handleParentCapture = () => {
console.log(`父元素React事件捕獲`);
};
handleChileCapture = () => {
console.log(`子元素React事件捕獲`);
};
render() {
return (
<div
ref={this.parentRef}
onClick={this.handleParentBubble}
onClickCapture={this.handleParentCapture}
>
<div
ref={this.childRef}
onClick={this.handleChildBubble}
onClickCapture={this.handleChileCapture}
>
事件處理測(cè)試
</div>
</div>
);
}
}
export default Test;執(zhí)行順序
e.stopPropagation()只能阻止react合成事件的冒泡和document原生事件冒泡,并不能阻止自己和父元素原生事件的冒泡。

e.nativeEvent.stopImmediatePropagation()只能阻止document原生事件冒泡。

e.preventDefault()和不執(zhí)行一樣

e.nativeEvent.stopPropagation()只能阻止document原生事件冒泡。

如果我們?cè)谧釉脑暿录锩孀柚姑芭荩甲柚沽恕?/p>
import React from "react";
class Test extends React.Component {
parentRef;
childRef;
constructor(props) {
super(props);
this.parentRef = React.createRef();
this.childRef = React.createRef();
}
componentDidMount() {
document.addEventListener(
"click",
() => {
console.log(`document原生事件捕獲`);
},
true
);
document.addEventListener("click", () => {
console.log(`document原生事件冒泡`);
});
this.parentRef.current.addEventListener(
"click",
() => {
console.log(`父元素原生事件捕獲`);
},
true
);
this.parentRef.current.addEventListener("click", () => {
console.log(`父元素原生事件冒泡`);
});
this.childRef.current.addEventListener(
"click",
() => {
console.log(`子元素原生事件捕獲`);
},
true
);
this.childRef.current.addEventListener("click", (e) => {
e.stopPropagation();
console.log(`子元素原生事件冒泡`);
});
}
handleParentBubble = () => {
console.log(`父元素React事件冒泡`);
};
handleChildBubble = (e) => {
console.log(`子元素React事件冒泡`);
};
handleParentCapture = () => {
console.log(`父元素React事件捕獲`);
};
handleChileCapture = () => {
console.log(`子元素React事件捕獲`);
};
render() {
return (
<div
ref={this.parentRef}
onClick={this.handleParentBubble}
onClickCapture={this.handleParentCapture}
>
<div
ref={this.childRef}
onClick={this.handleChildBubble}
onClickCapture={this.handleChileCapture}
>
事件處理測(cè)試
</div>
</div>
);
}
}
export default Test;執(zhí)行順序

在子元素的原聲事件里面,阻止了所有的冒泡。同時(shí)也阻止了react事件。
在父元素原生事件中阻止冒泡
import React from "react";
class Test extends React.Component {
parentRef;
childRef;
constructor(props) {
super(props);
this.parentRef = React.createRef();
this.childRef = React.createRef();
}
componentDidMount() {
document.addEventListener(
"click",
() => {
console.log(`document原生事件捕獲`);
},
true
);
document.addEventListener("click", () => {
console.log(`document原生事件冒泡`);
});
this.parentRef.current.addEventListener(
"click",
() => {
console.log(`父元素原生事件捕獲`);
},
true
);
this.parentRef.current.addEventListener("click", (e) => {
e.stopPropagation();
console.log(`父元素原生事件冒泡`);
});
this.childRef.current.addEventListener(
"click",
() => {
console.log(`子元素原生事件捕獲`);
},
true
);
this.childRef.current.addEventListener("click", (e) => {
console.log(`子元素原生事件冒泡`);
});
}
handleParentBubble = () => {
console.log(`父元素React事件冒泡`);
};
handleChildBubble = (e) => {
console.log(`子元素React事件冒泡`);
};
handleParentCapture = () => {
console.log(`父元素React事件捕獲`);
};
handleChileCapture = () => {
console.log(`子元素React事件捕獲`);
};
render() {
return (
<div
ref={this.parentRef}
onClick={this.handleParentBubble}
onClickCapture={this.handleParentCapture}
>
<div
ref={this.childRef}
onClick={this.handleChildBubble}
onClickCapture={this.handleChileCapture}
>
事件處理測(cè)試
</div>
</div>
);
}
}
export default Test;執(zhí)行順序

父元素原生事件中阻止冒泡阻止了react事件
阻止document原生事件的冒泡并不會(huì)阻止了react事件
document.addEventListener("click", (e) => {
e.stopPropagation();
console.log(`document原生事件冒泡`);
});
結(jié)論
react捕獲事件快于原生捕獲事件的執(zhí)行
react冒泡事件慢于原生冒泡事件的執(zhí)行
原生冒泡事件會(huì)阻止react事件。
以上就是深入了解React中的合成事件的詳細(xì)內(nèi)容,更多關(guān)于React合成事件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React+Antd+Redux實(shí)現(xiàn)待辦事件的方法
這篇文章主要介紹了React+Antd+Redux實(shí)現(xiàn)待辦事件的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
React Native 集成 ArcGIS 地圖的詳細(xì)過程
ArcGIS官方提供了 JavaScript SDK,也提供了 ArcGIS-Runtime-SDK-iOS,但是并沒有提供 React Native的版本,所以這里使用了 react-native-arcgis-mapview 庫,本文給大家介紹React Native 集成 ArcGIS 地圖的詳細(xì)過程,感興趣的朋友跟隨小編一起看看吧2024-06-06
基于React-Dropzone開發(fā)上傳組件功能(實(shí)例演示)
這篇文章主要介紹了基于React-Dropzone開發(fā)上傳組件,主要講述的是在React-Flask框架上開發(fā)上傳組件的技巧,需要的朋友可以參考下2021-08-08
解決React報(bào)錯(cuò)Expected an assignment or funct
這篇文章主要為大家介紹了React報(bào)錯(cuò)Expected an assignment or function call and instead saw an expression解決方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
React實(shí)現(xiàn)翻頁時(shí)鐘的代碼示例
本文給大家介紹了React實(shí)現(xiàn)翻頁時(shí)鐘的代碼示例,翻頁時(shí)鐘把數(shù)字分為上下兩部分,翻頁效果的實(shí)現(xiàn)需要通過設(shè)置 position 把所有的數(shù)組放在同一個(gè)位置疊加起來,文中有詳細(xì)的代碼講解,需要的朋友可以參考下2023-08-08
解析react?函數(shù)組件輸入卡頓問題?usecallback?react.memo
useMemo是一個(gè)react hook,我們可以使用它在組件中包裝函數(shù)??梢允褂盟鼇泶_保該函數(shù)中的值僅在依賴項(xiàng)之一發(fā)生變化時(shí)才重新計(jì)算,這篇文章主要介紹了react?函數(shù)組件輸入卡頓問題?usecallback?react.memo,需要的朋友可以參考下2022-07-07

