React Portallar bilan hodisa pufakchalarini nazorat qilishga chuqur kirish. Hodisalarni tanlab tarqatishni va bashorat qilinadigan interfeyslarni qanday yaratishni o'rganing.
React Portal Hodisa Pufakchalarini Nazorat qilish: Tanlangan Hodisa Tarqalishi
React Portallar standart React komponent ierarxiyasidan tashqarida komponentlarni render qilish uchun kuchli usulni taqdim etadi. Bu modallar, tooltiplar va overlaylar kabi vizual elementlarni mantiqiy ota-onadan mustaqil ravishda joylashtirish kerak bo'lgan vaziyatlar uchun juda foydali bo'lishi mumkin. Biroq, DOM daraxtidan bunday ajralish hodisa pufakchalari bilan murakkabliklarni keltirib chiqarishi mumkin, agar ehtiyotkorlik bilan boshqarilmasa, kutilmagan xatti-harakatlarga olib kelishi mumkin. Ushbu maqola React Portallar bilan hodisa pufakchalarining murakkab jihatlarini o'rganadi va istalgan komponent o'zaro ta'sirini amalga oshirish uchun hodisalarni tanlab tarqatish strategiyalarini taqdim etadi.
DOMda Hodisa Pufakchalarini Tushunish
React Portallariga kirishdan oldin, Hujjat Ob'ekt Modeli (DOM)dagi hodisa pufakchalari asosiy tushunchasini tushunish muhimdir. HTML elementida hodisa yuz berganda, u avval ushbu elementga (maqsadga) biriktirilgan hodisa tinglovchisini ishga tushiradi. Keyin, hodisa DOM daraxti bo'ylab "pufaklanadi", hujjatning ildizigacha (window) har bir ota-ona elementida xuddi shu hodisa tinglovchisini ishga tushiradi. Ushbu xatti-harakat hodisalarni boshqarish uchun yanada samarali usulni ta'minlaydi, chunki siz har bir bola elementi uchun alohida tinglovchilar o'rnatish o'rniga ota-ona elementiga bitta hodisa tinglovchisini biriktirishingiz mumkin.
Misol uchun, quyidagi HTML tuzilishini ko'rib chiqing:
<div id="parent">
<button id="child">Meni bosing</button>
</div>
Agar siz #child tugmasi va #parent diviga click hodisaning tinglovchisini biriktirsangiz, tugmani bosish avval tugmadagi hodisa tinglovchisini ishga tushiradi. Keyin, hodisa ota-ona diviga qarab pufaklanadi va uning ham click hodisaning tinglovchisini ishga tushiradi.
React Portallari va Hodisa Pufakchalari Bilang Murakkabliklar
React Portallari o'z bolalarini DOMda boshqa joyda render qiladi, bu esa komponent daraxtidagi asl ota-ona bilan standart React komponent ierarxiyasining aloqasini samarali ravishda uzadi. React komponent daraxti yaxlit tursa ham, DOM tuzilishi o'zgartiriladi. Bu o'zgarish hodisa pufakchalari bilan muammolarga olib kelishi mumkin. Dastlab, portal ichidan kelgan hodisalar hali ham DOM daraxti bo'ylab pufaklanadi, bu esa React dasturidan tashqaridagi elementlarda yoki dastur ichidagi kutilmagan ota-ona elementlarida portal tarkibi render qilinadigan *DOM daraxtida* joylashgan bo'lsa, hodisa tinglovchilarini ishga tushirishi mumkin. Bu pufaklanish DOMda sodir bo'ladi, React komponent daraxtida emas.
React portali yordamida render qilingan modal komponentini o'z ichiga olgan vaziyatni ko'rib chiqing. Modal tugmani o'z ichiga oladi. Agar siz tugmani bossangiz, hodisa body elementiga (portal orqali modal render qilinadigan joy) va keyin DOM tuzilishiga qarab boshqa elementlarga pufaklanadi. Agar boshqa elementlarning har qandayida bosish tinglovchilari bo'lsa, ular kutilmaganda ishga tushishi mumkin, bu esa istalmagan yon ta'sirlarga olib keladi.
React Portallari Bilang Hodisa Tarqalishini Nazorat Qilish
React Portallari keltirib chiqaradigan hodisa pufakchalari muammolarini hal qilish uchun biz hodisa tarqalishini tanlab nazorat qilishimiz kerak. Buning bir nechta usullari mavjud:
1. stopPropagation() dan Foydalanish
Eng oddiy usul - hodisa ob'ektida stopPropagation() usulidan foydalanish. Bu usul hodisaning DOM daraxtida yanada pufaklanishini oldini oladi. Siz portal ichidagi elementning hodisa tinglovchisi ichida stopPropagation() ni chaqirishingiz mumkin.
Namuna:
import React from 'react';
import ReactDOM from 'react-dom';
const modalRoot = document.getElementById('modal-root'); // HTML'da modal-root elementingiz borligiga ishonch hosil qiling
function Modal(props) {
return ReactDOM.createPortal(
<div className="modal" onClick={(e) => e.stopPropagation()}>
<div className="modal-content">
{props.children}
</div>
</div>,
modalRoot
);
}
function App() {
const [showModal, setShowModal] = React.useState(false);
return (
<div>
<button onClick={() => setShowModal(true)}>Modani ochish</button>
{showModal && (
<Modal>
<button onClick={() => alert('Modal ichidagi tugma bosildi!')}>Modal ichidagi tugmani bosing</button>
</Modal>
)}
<div onClick={() => alert('Modadan tashqari bosildi!')}>
Modadan tashqari shu yerga bosing
</div>
</div>
);
}
export default App;
Ushbu misolda, .modal diviga biriktirilgan onClick tinglovchisi e.stopPropagation() ni chaqiradi. Bu modal ichidagi bosishlarning modadan tashqari <div> dagi onClick tinglovchisini ishga tushirishini oldini oladi.
E'tiborga olish kerak bo'lganlar:
stopPropagation()hodisaning DOM daraxti bo'ylab yuqoriroqda joylashgan boshqa hodisa tinglovchilarini ishga tushirishini oldini oladi, ular React dasturi bilan bog'liqmi yoki yo'qmi.- Bu usuldan ehtiyotkorlik bilan foydalaning, chunki u hodisa pufakchalari xatti-harakatlariga tayanadigan boshqa hodisa tinglovchilari bilan aralashishi mumkin.
2. Maqsadga Qarab Shartli Hodisa Boshqarish
Boshqa bir yondashuv - hodisa maqsadiga qarab shartli ravishda hodisalarni boshqarish. Siz hodisa tinglovchisi mantiqini bajarishdan oldin hodisa portal ichida ekanligini tekshirishingiz mumkin. Bu sizga portal tashqarisidan kelib chiqqan hodisalarni tanlab e'tiborsiz qoldirishga imkon beradi.
Namuna:
import React from 'react';
import ReactDOM from 'react-dom';
const modalRoot = document.getElementById('modal-root');
function Modal(props) {
return ReactDOM.createPortal(
<div className="modal">
<div className="modal-content">
{props.children}
</div>
</div>,
modalRoot
);
}
function App() {
const [showModal, setShowModal] = React.useState(false);
const handleClickOutsideModal = (event) => {
if (showModal && !modalRoot.contains(event.target)) {
alert('Modadan tashqari bosildi!');
setShowModal(false);
}
};
React.useEffect(() => {
document.addEventListener('mousedown', handleClickOutsideModal);
return () => {
document.removeEventListener('mousedown', handleClickOutsideModal);
};
}, [showModal]);
return (
<div>
<button onClick={() => setShowModal(true)}>Modani ochish</button>
{showModal && (
<Modal>
<button onClick={() => alert('Modal ichidagi tugma bosildi!')}>Modal ichidagi tugmani bosing</button>
</Modal>
)}
</div>
);
}
export default App;
Ushbu misolda, handleClickOutsideModal funksiyasi hodisa maqsadining (event.target) modalRoot elementini o'z ichiga olganligini tekshiradi. Agar u o'z ichiga olmagan bo'lsa, bu bosish modadan tashqarida sodir bo'lganligini bildiradi va modal yopiladi. Ushbu yondashuv modal yoki shunga o'xshash komponent tashqarisida bosish mantiqini ishga tushirishni istaganingizda foydali bo'lishi mumkin.
E'tiborga olish kerak bo'lganlar:
- Ushbu yondashuv portal render qilinadigan asosiy elementga (masalan,
modalRoot) havola qilishni talab qiladi. - Bu hodisa maqsadini qo'lda tekshirishni o'z ichiga oladi, bu portal ichidagi katakli elementlar uchun murakkabroq bo'lishi mumkin.
- Foydalanuvchi modal yoki shunga o'xshash komponent tashqarisida bosganida ma'lum bir harakatni ishga tushirishni istagan vaziyatlar uchun foydali bo'lishi mumkin.
3. Capture Bosqich Hodisa Tinglovchilaridan Foydalanish
Hodisa pufakchalari dastlabki xatti-harakatlar bo'lsa-da, hodisalar pufaklanish bosqichidan oldin "capture" bosqichidan ham o'tadi. Capture bosqichi davomida hodisa windowdan maqsad elementigacha DOM daraxti bo'ylab pastga qarab harakatlanadi. Siz hodisa tinglovchilarini capture bosqichi davomida tinglaydigan hodisa tinglovchilarini biriktirishingiz mumkin, bu esa hodisa tinglovchisini qo'shishda useCapture parametrini true ga o'rnatish orqali amalga oshiriladi.
Hujjatga (yoki boshqa mos keladigan ota-ona elementiga) capture bosqichi hodisa tinglovchisini biriktirish orqali siz hodisalarni portalga yetib borishidan oldin ularni tutib olishingiz va potentsial ravishda ularning pufaklanishini oldini olishingiz mumkin. Agar hodisa boshqa elementlarga yetib borishidan oldin unga asoslangan biron bir harakatni amalga oshirish kerak bo'lsa, bu foydali bo'lishi mumkin.
Namuna:
import React from 'react';
import ReactDOM from 'react-dom';
const modalRoot = document.getElementById('modal-root');
function Modal(props) {
return ReactDOM.createPortal(
<div className="modal">
<div className="modal-content">
{props.children}
</div>
</div>,
modalRoot
);
}
function App() {
const [showModal, setShowModal] = React.useState(false);
const handleCapture = (event) => {
// Agar hodisa modal-rootdan kelib chiqqan bo'lsa, hech narsa qilmang
if (modalRoot.contains(event.target)) {
return;
}
// Agar hodisa modaldan tashqari kelib chiqqan bo'lsa, uning pufaklanishini oldini oling
console.log('Hodisa modaldan tashqari tutib olindi!', event.target);
event.stopPropagation();
setShowModal(false);
};
React.useEffect(() => {
document.addEventListener('click', handleCapture, true); // Capture bosqichi!
return () => {
document.removeEventListener('click', handleCapture, true);
};
}, [showModal]);
return (
<div>
<button onClick={() => setShowModal(true)}>Modani ochish</button>
{showModal && (
<Modal>
<button onClick={() => alert('Modal ichidagi tugma bosildi!')}>Modal ichidagi tugmani bosing</button>
</Modal>
)}
</div>
);
}
export default App;
Ushbu misolda, handleCapture funksiyasi useCapture: true opsiyasi yordamida hujjatga biriktirilgan. Bu shuni anglatadiki, handleCapture sahifadagi boshqa har qanday bosish tinglovchilaridan *oldin* chaqiriladi. Funksiya hodisa maqsadi modalRoot ichida ekanligini tekshiradi. Agar u ichida bo'lsa, hodisa pufaklanishiga ruxsat beriladi. Agar u ichida bo'lmasa, hodisaning event.stopPropagation() dan foydalanib pufaklanishi to'xtatiladi va modal yopiladi. Bu modaldan tashqari bosishlarning yuqoriga qarab tarqalishini oldini oladi.
E'tiborga olish kerak bo'lganlar:
- Capture bosqichi hodisa tinglovchilari pufaklanish bosqichi tinglovchilaridan *oldin* bajariladi, shuning uchun ular ehtiyotkorlik bilan ishlatilmasa, sahifadagi boshqa hodisa tinglovchilari bilan aralashishi mumkin.
- Ushbu yondashuvni tushunish va disk raskadrovka qilish
stopPropagation()yoki shartli hodisa boshqarishdan ko'ra murakkabroq bo'lishi mumkin. - Hodisa oqimining boshida hodisalarni tutib olish kerak bo'lgan maxsus vaziyatlarda foydali bo'lishi mumkin.
4. Reactning Sintetik Hodisalari va Portalning DOM Pozitsiyasi
Reactning Sintetik Hodisalar tizimini eslab qolish muhim. React mahalliy DOM hodisalarini Sintetik Hodisalar bilan o'rab oladi, ular brauzerdan-brauzerga mos keladigan o'ramlardir. Bu abstraksiya Reactda hodisa boshqarishni soddalashtiradi, ammo buning natijasida asosiy DOM hodisasi hali ham sodir bo'lishini bildiradi. React hodisa tinglovchilari asosiy elementga biriktiriladi va keyin mos komponentlarga delegatsiya qilinadi. Biroq, Portallar DOM render qilish joyini o'zgartiradi, lekin React komponent tuzilishi bir xil qoladi.
Shuning uchun, portal tarkibi DOMning boshqa qismida render qilingan bo'lsa ham, React hodisa tizimi komponent daraxtiga asoslangan holda ishlaydi. Bu sizga portal ichida Reactning hodisa boshqarish mexanizmlaridan (masalan, onClick) foydalanish imkonini beradi, agar siz DOMdan tashqarida pufaklanishni aniq oldini olishni istamasangiz.
React Portallari Bilang Hodisa Pufakchalari Uchun Eng Yaxshi Amaliyotlar
React Portallari va hodisa pufakchalari bilan ishlashda yodda tutishingiz kerak bo'lgan bir nechta eng yaxshi amaliyotlar:
- DOM Tuzilishini Tushuning: Portal qayerda render qilinishini DOM tuzilishini diqqat bilan tahlil qilib, hodisalar daraxt bo'ylab qanday pufaklanishini tushuning.
stopPropagation()dan Kamdan-kam Foydalaning: Faqatgina zarur bo'lgandastopPropagation()dan foydalaning, chunki u kutilmagan yon ta'sirlarga olib kelishi mumkin.- Shartli Hodisa Boshqarishni Ko'rib Chiqing: Portal ichidan kelib chiqqan hodisalarni tanlab boshqarish uchun hodisa maqsadiga asoslangan shartli hodisa boshqarishdan foydalaning.
- Capture Bosqichi Hodisa Tinglovchilaridan foydalaning: Maxsus vaziyatlarda, hodisalarni hodisa oqimining boshida tutib olish uchun capture bosqichi hodisa tinglovchilaridan foydalanishni ko'rib chiqing.
- To'liq Sinovdan O'tkazing: Hodisa pufakchalari kutilganidek ishlayotganligiga va kutilmagan yon ta'sirlar yo'qligiga ishonch hosil qilish uchun komponentlaringizni to'liq sinovdan o'tkazing.
- Kodni Hujjatlashtiring: Boshqa dasturchilarga kodni tushunish va qo'llab-quvvatlashni osonlashtirish uchun React Portallari bilan hodisa pufakchalarini qanday boshqarayotganligingizni tushuntirish uchun kodni aniq hujjatlashtiring.
- Erişilebilirlikni Ko'rib Chiqing: Hodisa tarqalishini boshqarishda, o'zgarishlaringiz dasturingizning erişilebilirligiga salbiy ta'sir qilmasligiga ishonch hosil qiling. Masalan, klaviatura hodisalarining tasodifan bloklanishini oldini oling.
- Ishlash: Haddan tashqari ko'p hodisa tinglovchilarini, ayniqsa
documentyokiwindowob'ektlariga biriktirishdan saqlaning, chunki bu ish qobiliyatiga ta'sir qilishi mumkin. Imkon bo'lsa, hodisa tinglovchilarini "debounce" yoki "throttle" qiling.
Amaliy Hayot Namunalari
React Portallari bilan hodisa pufakchalarini nazorat qilish muhim bo'lgan bir nechta amaliy hayot namunalari:
- Modallar: Yuqoridagi misollarda ko'rsatilganidek, modallar React Portallarining klassik ishlatiladigan holati. Modal ichidagi bosishlarning modadan tashqari harakatlarni ishga tushirishini oldini olish yaxshi foydalanuvchi tajribasi uchun juda muhimdir.
- Tooltiplar: Tooltiplar ko'pincha maqsadli elementga nisbatan joylashtirish uchun portallar yordamida render qilinadi. Siz tooltipdagi bosishlarning ota-ona elementini yopishini oldini olishni xohlashingiz mumkin.
- Kontekst Menulari: Kontekst menulari odatda sichqoncha kursori yaqinida joylashtirish uchun portallar yordamida render qilinadi. Siz kontekst menusidagi bosishlarning sahifaning tagidagi harakatlarni ishga tushirishini oldini olishni xohlashingiz mumkin.
- Dropdown Menulari: Kontekst menulariga o'xshab, dropdown menulari ko'pincha portallardan foydalanadi. Hodisa tarqalishini nazorat qilish menyu ichidagi bosishlarning uni erta yopishini oldini olish uchun zarurdir.
- Bildirishnomalar: Bildirishnomalar ekranning ma'lum bir hududida (masalan, yuqori o'ng burchakda) joylashtirish uchun portallar yordamida render qilinishi mumkin. Bildirishnomadagi bosishlarning sahifaning tagidagi harakatlarni ishga tushirishini oldini olish foydalilikni yaxshilaydi.
Xulosa
React Portallari standart React komponent ierarxiyasidan tashqarida komponentlarni render qilish uchun kuchli usulni taqdim etadi, ammo ular hodisa pufakchalari bilan murakkabliklarni ham keltirib chiqaradi. DOM hodisa modelini tushunish va stopPropagation(), shartli hodisa boshqarish va capture bosqichi hodisa tinglovchilari kabi usullardan foydalanish orqali siz hodisa tarqalishini samarali nazorat qilishingiz va yanada bashorat qilinadigan va qo'llab-quvvatlanadigan foydalanuvchi interfeyslarini yaratishingiz mumkin. DOM tuzilishi, erişilebilirlik va ish qobiliyatini ehtiyotkorlik bilan ko'rib chiqish React Portallari va hodisa pufakchalari bilan ishlashda muhimdir. Hodisa boshqarish kutilganidek ishlayotganligiga ishonch hosil qilish uchun komponentlaringizni to'liq sinovdan o'tkazish va kodni hujjatlashtirishni unutmang.
React Portallari bilan hodisa pufakchalarini nazorat qilishni o'zlashtirish orqali siz dasturingiz bilan uzluksiz integratsiya qilinadigan murakkab va foydalanuvchiga yo'naltirilgan komponentlarni yaratishingiz mumkin, bu esa umumiy foydalanuvchi tajribasini yaxshilaydi va kod bazangizni yanada mustahkam qiladi. Dastlabki amaliyotlar rivojlanar ekan, hodisa boshqarishning nozik jihatlarini kuzatib borish sizning dasturlaringiz global miqyosda javobgar, erişilebilir va qo'llab-quvvatlanadigan bo'lib qolishini ta'minlaydi.