ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ಗಳಿಗಾಗಿ ದೃಢವಾದ ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಿ. ಈ ಸಮಗ್ರ ಮಾರ್ಗದರ್ಶಿ, ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಹೇಗೆ DOM ಟ್ರೀ ಅಸಮಾನತೆಗಳನ್ನು ಪರಿಣಾಮಕಾರಿಯಾಗಿ ನಿವಾರಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ವಿವರಿಸುತ್ತದೆ, ನಿಮ್ಮ ಜಾಗತಿಕ ವೆಬ್ ಅಪ್ಲಿಕೇಶನ್ಗಳಲ್ಲಿ ಸುಗಮ ಬಳಕೆದಾರ ಸಂವಹನವನ್ನು ಖಚಿತಪಡಿಸುತ್ತದೆ.
ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್ನಲ್ಲಿ ಪರಿಣತಿ: ಜಾಗತಿಕ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗಾಗಿ DOM ಟ್ರೀಗಳಾದ್ಯಂತ ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್
ವೆಬ್ ಡೆವಲಪ್ಮೆಂಟ್ನ ವಿಸ್ತಾರವಾದ ಮತ್ತು ಪರಸ್ಪರ ಸಂಪರ್ಕ ಹೊಂದಿದ ಜಗತ್ತಿನಲ್ಲಿ, ಜಾಗತಿಕ ಪ್ರೇಕ್ಷಕರಿಗೆ ಅನುಗುಣವಾಗಿ ಅರ್ಥಗರ್ಭಿತ ಮತ್ತು ಸ್ಪಂದಿಸುವ ಬಳಕೆದಾರ ಇಂಟರ್ಫೇಸ್ಗಳನ್ನು ನಿರ್ಮಿಸುವುದು ಅತ್ಯಂತ ಮಹತ್ವದ್ದಾಗಿದೆ. ರಿಯಾಕ್ಟ್, ತನ್ನ ಕಾಂಪೊನೆಂಟ್-ಆಧಾರಿತ ಆರ್ಕಿಟೆಕ್ಚರ್ನೊಂದಿಗೆ, ಇದನ್ನು ಸಾಧಿಸಲು ಶಕ್ತಿಯುತ ಸಾಧನಗಳನ್ನು ಒದಗಿಸುತ್ತದೆ. ಇವುಗಳಲ್ಲಿ, ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ಗಳು ಪೋಷಕ ಕಾಂಪೊನೆಂಟ್ನ ಶ್ರೇಣಿಯ ಹೊರಗೆ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ DOM ನೋಡ್ಗೆ ಚಿಲ್ಡ್ರನ್ ಅನ್ನು ರೆಂಡರ್ ಮಾಡಲು ಹೆಚ್ಚು ಪರಿಣಾಮಕಾರಿ ಯಾಂತ್ರಿಕವಾಗಿ ಎದ್ದು ಕಾಣುತ್ತವೆ. ತಮ್ಮ ಪೋಷಕರ ಸ್ಟೈಲಿಂಗ್ ಅಥವಾ `z-index` ಸ್ಟ್ಯಾಕಿಂಗ್ ಸಂದರ್ಭದ ನಿರ್ಬಂಧಗಳಿಂದ ಮುಕ್ತವಾಗಬೇಕಾದ ಮೋಡಲ್ಗಳು, ಟೂಲ್ಟಿಪ್ಗಳು, ಡ್ರಾಪ್ಡೌನ್ಗಳು, ಮತ್ತು ನೋಟಿಫಿಕೇಶನ್ಗಳಂತಹ UI ಅಂಶಗಳನ್ನು ರಚಿಸಲು ಈ ಸಾಮರ್ಥ್ಯವು ಅಮೂಲ್ಯವಾಗಿದೆ.
ಪೋರ್ಟಲ್ಗಳು ಅಪಾರವಾದ ನಮ್ಯತೆಯನ್ನು ನೀಡಿದರೂ, ಅವು ಒಂದು ವಿಶಿಷ್ಟ ಸವಾಲನ್ನು ಪರಿಚಯಿಸುತ್ತವೆ: ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್, ವಿಶೇಷವಾಗಿ ಡಾಕ್ಯುಮೆಂಟ್ ಆಬ್ಜೆಕ್ಟ್ ಮಾಡೆಲ್ (DOM) ಟ್ರೀಯ ವಿವಿಧ ಭಾಗಗಳಲ್ಲಿ ಸಂಭವಿಸುವ ಸಂವಹನಗಳನ್ನು ನಿಭಾಯಿಸುವಾಗ. ಬಳಕೆದಾರರು ಪೋರ್ಟಲ್ ಮೂಲಕ ರೆಂಡರ್ ಆದ ಎಲಿಮೆಂಟ್ನೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸಿದಾಗ, DOM ಮೂಲಕ ಈವೆಂಟ್ನ ಪ್ರಯಾಣವು ರಿಯಾಕ್ಟ್ ಕಾಂಪೊನೆಂಟ್ ಟ್ರೀಯ ತಾರ್ಕಿಕ ರಚನೆಯೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗದಿರಬಹುದು. ಇದನ್ನು ಸರಿಯಾಗಿ ನಿಭಾಯಿಸದಿದ್ದರೆ ಇದು ಅನಿರೀಕ್ಷಿತ ವರ್ತನೆಗೆ ಕಾರಣವಾಗಬಹುದು. ಈ ಸಮಸ್ಯೆಗೆ ಪರಿಹಾರ, ನಾವು ಆಳವಾಗಿ ಅನ್ವೇಷಿಸಲಿರುವಂತೆ, ಒಂದು ಮೂಲಭೂತ ವೆಬ್ ಡೆವಲಪ್ಮೆಂಟ್ ಪರಿಕಲ್ಪನೆಯಲ್ಲಿದೆ: ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್.
ಈ ಸಮಗ್ರ ಮಾರ್ಗದರ್ಶಿ ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ಗಳೊಂದಿಗೆ ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್ ಅನ್ನು ನಿಗೂಢತೆಯಿಂದ ಹೊರತರುತ್ತದೆ. ನಾವು ರಿಯಾಕ್ಟ್ನ ಸಿಂಥೆಟಿಕ್ ಈವೆಂಟ್ ಸಿಸ್ಟಮ್ನ ಜಟಿಲತೆಗಳನ್ನು ಪರಿಶೀಲಿಸುತ್ತೇವೆ, ಈವೆಂಟ್ ಬಬ್ಲಿಂಗ್ ಮತ್ತು ಕ್ಯಾಪ್ಚರಿಂಗ್ನ ಯಾಂತ್ರಿಕತೆಯನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುತ್ತೇವೆ, ಮತ್ತು ಮುಖ್ಯವಾಗಿ, ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ಗಳ ಜಾಗತಿಕ ವ್ಯಾಪ್ತಿ ಅಥವಾ ಅವುಗಳ UI ನ ಸಂಕೀರ್ಣತೆಯನ್ನು ಲೆಕ್ಕಿಸದೆ, ಸುಗಮ ಮತ್ತು ನಿರೀಕ್ಷಿತ ಬಳಕೆದಾರ ಅನುಭವಗಳನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು ದೃಢವಾದ ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಅನ್ನು ಹೇಗೆ ಕಾರ್ಯಗತಗೊಳಿಸಬೇಕು ಎಂಬುದನ್ನು ಪ್ರದರ್ಶಿಸುತ್ತೇವೆ.
ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ಗಳನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು: DOM ಶ್ರೇಣಿಗಳಾದ್ಯಂತ ಒಂದು ಸೇತುವೆ
ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್ಗೆ ಧುಮುಕುವ ಮೊದಲು, ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ಗಳು ಯಾವುವು ಮತ್ತು ಆಧುನಿಕ ವೆಬ್ ಡೆವಲಪ್ಮೆಂಟ್ನಲ್ಲಿ ಅವು ಏಕೆ ಅಷ್ಟು ನಿರ್ಣಾಯಕವಾಗಿವೆ ಎಂಬುದರ ಬಗ್ಗೆ ನಮ್ಮ ತಿಳುವಳಿಕೆಯನ್ನು ದೃಢಪಡಿಸೋಣ. ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ ಅನ್ನು `ReactDOM.createPortal(child, container)` ಬಳಸಿ ರಚಿಸಲಾಗಿದೆ, ಇಲ್ಲಿ `child` ಯಾವುದೇ ರೆಂಡರ್ ಮಾಡಬಹುದಾದ ರಿಯಾಕ್ಟ್ ಚೈಲ್ಡ್ (ಉದಾ., ಎಲಿಮೆಂಟ್, ಸ್ಟ್ರಿಂಗ್, ಅಥವಾ ಫ್ರಾಗ್ಮೆಂಟ್), ಮತ್ತು `container` ಒಂದು DOM ಎಲಿಮೆಂಟ್ ಆಗಿದೆ.
ಜಾಗತಿಕ UI/UX ಗಾಗಿ ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ಗಳು ಏಕೆ ಅತ್ಯಗತ್ಯ
ಒಂದು ಮೋಡಲ್ ಡೈಲಾಗ್ ಅನ್ನು ಪರಿಗಣಿಸಿ, ಅದರ ಪೋಷಕ ಕಾಂಪೊನೆಂಟ್ನ `z-index` ಅಥವಾ `overflow` ಗುಣಲಕ್ಷಣಗಳನ್ನು ಲೆಕ್ಕಿಸದೆ, ಅದು ಎಲ್ಲಾ ಇತರ ಕಂಟೆಂಟ್ನ ಮೇಲೆ ಕಾಣಿಸಿಕೊಳ್ಳಬೇಕಾಗುತ್ತದೆ. ಈ ಮೋಡಲ್ ಅನ್ನು ಸಾಮಾನ್ಯ ಚೈಲ್ಡ್ ಆಗಿ ರೆಂಡರ್ ಮಾಡಿದ್ದರೆ, ಅದು `overflow: hidden` ಪೋಷಕರಿಂದ ತುಂಡಾಗಬಹುದು ಅಥವಾ `z-index` ಸಂಘರ್ಷಗಳಿಂದಾಗಿ ಸಹೋದರ ಎಲಿಮೆಂಟ್ಗಳ ಮೇಲೆ ಕಾಣಿಸಿಕೊಳ್ಳಲು ಹೆಣಗಾಡಬಹುದು. ಪೋರ್ಟಲ್ಗಳು ಈ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸುತ್ತವೆ. ಮೋಡಲ್ ಅನ್ನು ಅದರ ರಿಯಾಕ್ಟ್ ಪೋಷಕ ಕಾಂಪೊನೆಂಟ್ನಿಂದ ತಾರ್ಕಿಕವಾಗಿ ನಿರ್ವಹಿಸಲು ಅನುವು ಮಾಡಿಕೊಡುತ್ತವೆ, ಆದರೆ ಅದನ್ನು ಭೌತಿಕವಾಗಿ ಒಂದು ಗೊತ್ತುಪಡಿಸಿದ DOM ನೋಡ್ಗೆ, ಸಾಮಾನ್ಯವಾಗಿ document.body ನ ಚೈಲ್ಡ್ ಆಗಿ ರೆಂಡರ್ ಮಾಡುತ್ತವೆ.
- ಕಂಟೇನರ್ ನಿರ್ಬಂಧಗಳಿಂದ ಪಾರಾಗುವುದು: ಪೋರ್ಟಲ್ಗಳು ಕಾಂಪೊನೆಂಟ್ಗಳಿಗೆ ತಮ್ಮ ಪೋಷಕ ಕಂಟೇನರ್ನ ದೃಶ್ಯ ಮತ್ತು ಸ್ಟೈಲಿಂಗ್ ನಿರ್ಬಂಧಗಳಿಂದ "ಪಾರಾಗಲು" ಅನುವು ಮಾಡಿಕೊಡುತ್ತವೆ. ವ್ಯೂಪೋರ್ಟ್ಗೆ ಸಂಬಂಧಿಸಿದಂತೆ ಅಥವಾ ಸ್ಟ್ಯಾಕಿಂಗ್ ಸಂದರ್ಭದ ತುದಿಯಲ್ಲಿ ತಮ್ಮನ್ನು ತಾವು ಇರಿಸಿಕೊಳ್ಳಬೇಕಾದ ಓವರ್ಲೇಗಳು, ಡ್ರಾಪ್ಡೌನ್ಗಳು, ಟೂಲ್ಟಿಪ್ಗಳು ಮತ್ತು ಡೈಲಾಗ್ಗಳಿಗೆ ಇದು ವಿಶೇಷವಾಗಿ ಉಪಯುಕ್ತವಾಗಿದೆ.
- ರಿಯಾಕ್ಟ್ ಕಾಂಟೆಕ್ಸ್ಟ್ ಮತ್ತು ಸ್ಟೇಟ್ ಅನ್ನು ನಿರ್ವಹಿಸುವುದು: ಬೇರೆ DOM ಸ್ಥಳದಲ್ಲಿ ರೆಂಡರ್ ಆಗಿದ್ದರೂ, ಪೋರ್ಟಲ್ ಮೂಲಕ ರೆಂಡರ್ ಆದ ಕಾಂಪೊನೆಂಟ್ ರಿಯಾಕ್ಟ್ ಟ್ರೀಯಲ್ಲಿ ತನ್ನ ಸ್ಥಾನವನ್ನು ಉಳಿಸಿಕೊಳ್ಳುತ್ತದೆ. ಇದರರ್ಥ ಅದು ಇನ್ನೂ ಕಾಂಟೆಕ್ಸ್ಟ್ ಅನ್ನು ಪ್ರವೇಶಿಸಬಹುದು, ಪ್ರಾಪ್ಸ್ಗಳನ್ನು ಸ್ವೀಕರಿಸಬಹುದು ಮತ್ತು ಸಾಮಾನ್ಯ ಚೈಲ್ಡ್ನಂತೆಯೇ ಅದೇ ಸ್ಟೇಟ್ ಮ್ಯಾನೇಜ್ಮೆಂಟ್ನಲ್ಲಿ ಭಾಗವಹಿಸಬಹುದು, ಇದು ಡೇಟಾ ಹರಿವನ್ನು ಸರಳಗೊಳಿಸುತ್ತದೆ.
- ವರ್ಧಿತ ಪ್ರವೇಶಸಾಧ್ಯತೆ: ಪ್ರವೇಶಸಾಧ್ಯ UI ಗಳನ್ನು ರಚಿಸಲು ಪೋರ್ಟಲ್ಗಳು ಪ್ರಮುಖ ಪಾತ್ರ ವಹಿಸಬಹುದು. ಉದಾಹರಣೆಗೆ, ಒಂದು ಮೋಡಲ್ ಅನ್ನು ನೇರವಾಗಿ
document.bodyಗೆ ರೆಂಡರ್ ಮಾಡಬಹುದು, ಇದು ಫೋಕಸ್ ಟ್ರ್ಯಾಪಿಂಗ್ ಅನ್ನು ನಿರ್ವಹಿಸಲು ಮತ್ತು ಸ್ಕ್ರೀನ್ ರೀಡರ್ಗಳು ಕಂಟೆಂಟ್ ಅನ್ನು ಉನ್ನತ ಮಟ್ಟದ ಡೈಲಾಗ್ ಎಂದು ಸರಿಯಾಗಿ ಅರ್ಥೈಸಿಕೊಳ್ಳುವುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು ಸುಲಭವಾಗಿಸುತ್ತದೆ. - ಜಾಗತಿಕ ಸ್ಥಿರತೆ: ಜಾಗತಿಕ ಪ್ರೇಕ್ಷಕರಿಗೆ ಸೇವೆ ಸಲ್ಲಿಸುವ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ, ಸ್ಥಿರವಾದ UI ವರ್ತನೆ ಅತ್ಯಗತ್ಯ. ಕ್ಯಾಸ್ಕೇಡಿಂಗ್ CSS ಸಮಸ್ಯೆಗಳು ಅಥವಾ DOM ಶ್ರೇಣಿಯ ಸಂಘರ್ಷಗಳೊಂದಿಗೆ ಹೋರಾಡದೆ, ಅಪ್ಲಿಕೇಶನ್ನ ವಿವಿಧ ಭಾಗಗಳಲ್ಲಿ ಪ್ರಮಾಣಿತ UI ಮಾದರಿಗಳನ್ನು (ಸ್ಥಿರ ಮೋಡಲ್ ವರ್ತನೆಯಂತಹ) ಕಾರ್ಯಗತಗೊಳಿಸಲು ಪೋರ್ಟಲ್ಗಳು ಡೆವಲಪರ್ಗಳಿಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತವೆ.
ಒಂದು ವಿಶಿಷ್ಟ ಸೆಟಪ್ ನಿಮ್ಮ index.html ನಲ್ಲಿ ಒಂದು ಮೀಸಲಾದ DOM ನೋಡ್ ಅನ್ನು ರಚಿಸುವುದನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ (ಉದಾ., <div id="modal-root"></div>) ಮತ್ತು ನಂತರ ಅದರಲ್ಲಿ ಕಂಟೆಂಟ್ ಅನ್ನು ರೆಂಡರ್ ಮಾಡಲು `ReactDOM.createPortal` ಅನ್ನು ಬಳಸುವುದು. ಉದಾಹರಣೆಗೆ:
// public/index.html
<body>
<div id="root"></div>
<div id="portal-root"></div>
</body>
// MyModal.js
import React from 'react';
import ReactDOM from 'react-dom';
const portalRoot = document.getElementById('portal-root');
const MyModal = ({ children, isOpen, onClose }) => {
if (!isOpen) return null;
return ReactDOM.createPortal(
<div className="modal-overlay" onClick={onClose}>
<div className="modal-content" onClick={e => e.stopPropagation()}>
{children}
<button onClick={onClose}>Close</button>
</div>
</div>,
portalRoot
);
};
export default MyModal;
ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್ ಗೊಂದಲ: DOM ಮತ್ತು ರಿಯಾಕ್ಟ್ ಟ್ರೀಗಳು ಭಿನ್ನವಾದಾಗ
ರಿಯಾಕ್ಟ್ನ ಸಿಂಥೆಟಿಕ್ ಈವೆಂಟ್ ಸಿಸ್ಟಮ್ ಒಂದು ಅದ್ಭುತವಾದ ಅಮೂರ್ತತೆ. ಇದು ಬ್ರೌಸರ್ ಈವೆಂಟ್ಗಳನ್ನು ಸಾಮಾನ್ಯಗೊಳಿಸುತ್ತದೆ, ವಿವಿಧ ಪರಿಸರಗಳಲ್ಲಿ ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್ ಅನ್ನು ಸ್ಥಿರಗೊಳಿಸುತ್ತದೆ ಮತ್ತು `document` ಮಟ್ಟದಲ್ಲಿ ಡೆಲಿಗೇಷನ್ ಮೂಲಕ ಈವೆಂಟ್ ಲಿಸನರ್ಗಳನ್ನು ಸಮರ್ಥವಾಗಿ ನಿರ್ವಹಿಸುತ್ತದೆ. ನೀವು ರಿಯಾಕ್ಟ್ ಎಲಿಮೆಂಟ್ಗೆ `onClick` ಹ್ಯಾಂಡ್ಲರ್ ಅನ್ನು ಲಗತ್ತಿಸಿದಾಗ, ರಿಯಾಕ್ಟ್ ಆ ನಿರ್ದಿಷ್ಟ DOM ನೋಡ್ಗೆ ನೇರವಾಗಿ ಈವೆಂಟ್ ಲಿಸನರ್ ಅನ್ನು ಸೇರಿಸುವುದಿಲ್ಲ. ಬದಲಾಗಿ, ಅದು ಆ ಈವೆಂಟ್ ಪ್ರಕಾರಕ್ಕೆ (ಉದಾ., `click`) ಒಂದೇ ಲಿಸನರ್ ಅನ್ನು `document` ಅಥವಾ ನಿಮ್ಮ ರಿಯಾಕ್ಟ್ ಅಪ್ಲಿಕೇಶನ್ನ ರೂಟ್ಗೆ ಲಗತ್ತಿಸುತ್ತದೆ.
ಒಂದು ನಿಜವಾದ ಬ್ರೌಸರ್ ಈವೆಂಟ್ (ಉದಾ., ಕ್ಲಿಕ್) ಸಂಭವಿಸಿದಾಗ, ಅದು ನೇಟಿವ್ DOM ಟ್ರೀಯ ಮೂಲಕ `document` ಗೆ ಬಬಲ್ ಆಗುತ್ತದೆ. ರಿಯಾಕ್ಟ್ ಈ ಈವೆಂಟ್ ಅನ್ನು ತಡೆಹಿಡಿಯುತ್ತದೆ, ಅದನ್ನು ತನ್ನ ಸಿಂಥೆಟಿಕ್ ಈವೆಂಟ್ ಆಬ್ಜೆಕ್ಟ್ನಲ್ಲಿ ಸುತ್ತುತ್ತದೆ, ಮತ್ತು ನಂತರ ಅದನ್ನು ಸೂಕ್ತ ರಿಯಾಕ್ಟ್ ಕಾಂಪೊನೆಂಟ್ಗಳಿಗೆ ಮರು-ರವಾನಿಸುತ್ತದೆ, ರಿಯಾಕ್ಟ್ ಕಾಂಪೊನೆಂಟ್ ಟ್ರೀಯ ಮೂಲಕ ಬಬ್ಲಿಂಗ್ ಅನ್ನು ಅನುಕರಿಸುತ್ತದೆ. ಈ ವ್ಯವಸ್ಥೆಯು ಪ್ರಮಾಣಿತ DOM ಶ್ರೇಣಿಯೊಳಗೆ ರೆಂಡರ್ ಆದ ಕಾಂಪೊನೆಂಟ್ಗಳಿಗೆ ಅದ್ಭುತವಾಗಿ ಕೆಲಸ ಮಾಡುತ್ತದೆ.
ಪೋರ್ಟಲ್ನ ವಿಶಿಷ್ಟತೆ: DOM ನಲ್ಲಿ ಒಂದು ಬಳಸುದಾರ
ಪೋರ್ಟಲ್ಗಳೊಂದಿಗೆ ಸವಾಲು ಇಲ್ಲಿದೆ: ಪೋರ್ಟಲ್ ಮೂಲಕ ರೆಂಡರ್ ಆದ ಎಲಿಮೆಂಟ್ ತಾರ್ಕಿಕವಾಗಿ ಅದರ ರಿಯಾಕ್ಟ್ ಪೋಷಕನ ಚೈಲ್ಡ್ ಆಗಿದ್ದರೂ, DOM ಟ್ರೀಯಲ್ಲಿ ಅದರ ಭೌತಿಕ ಸ್ಥಳವು ಸಂಪೂರ್ಣವಾಗಿ ಭಿನ್ನವಾಗಿರಬಹುದು. ನಿಮ್ಮ ಮುಖ್ಯ ಅಪ್ಲಿಕೇಶನ್ <div id="root"></div> ನಲ್ಲಿ ಮೌಂಟ್ ಆಗಿದ್ದರೆ ಮತ್ತು ನಿಮ್ಮ ಪೋರ್ಟಲ್ ಕಂಟೆಂಟ್ <div id="portal-root"></div> ಗೆ ರೆಂಡರ್ ಆದರೆ (`root` ನ ಸಹೋದರ), ಪೋರ್ಟಲ್ನ ಒಳಗಿನಿಂದ ಹುಟ್ಟುವ ಕ್ಲಿಕ್ ಈವೆಂಟ್ ತನ್ನ *ಸ್ವಂತ* ನೇಟಿವ್ DOM ಪಥದಲ್ಲಿ ಬಬಲ್ ಆಗುತ್ತದೆ, ಅಂತಿಮವಾಗಿ `document.body` ಮತ್ತು ನಂತರ `document` ಅನ್ನು ತಲುಪುತ್ತದೆ. ಇದು ಸಹಜವಾಗಿ `div#root` ಮೂಲಕ ಬಬಲ್ ಆಗಿ `div#root` ಒಳಗಿನ ಪೋರ್ಟಲ್ನ *ತಾರ್ಕಿಕ* ಪೋಷಕರ ಪೂರ್ವಜರಿಗೆ ಲಗತ್ತಿಸಲಾದ ಈವೆಂಟ್ ಲಿಸನರ್ಗಳನ್ನು ತಲುಪುವುದಿಲ್ಲ.
ಈ ಭಿನ್ನತೆಯ ಅರ್ಥವೇನೆಂದರೆ, ನೀವು ಪೋಷಕ ಎಲಿಮೆಂಟ್ನಲ್ಲಿ ಕ್ಲಿಕ್ ಹ್ಯಾಂಡ್ಲರ್ ಅನ್ನು ಇರಿಸಿದಾಗ ಅದರ ಎಲ್ಲಾ ಚಿಲ್ಡ್ರನ್ನಿಂದ ಈವೆಂಟ್ಗಳನ್ನು ಹಿಡಿಯಲು ನಿರೀಕ್ಷಿಸುವ ಸಾಂಪ್ರದಾಯಿಕ ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್ ಮಾದರಿಗಳು, ಆ ಚಿಲ್ಡ್ರನ್ ಪೋರ್ಟಲ್ನಲ್ಲಿ ರೆಂಡರ್ ಆದಾಗ ವಿಫಲವಾಗಬಹುದು ಅಥವಾ ಅನಿರೀಕ್ಷಿತವಾಗಿ ವರ್ತಿಸಬಹುದು. ಉದಾಹರಣೆಗೆ, ನಿಮ್ಮ ಮುಖ್ಯ `App` ಕಾಂಪೊನೆಂಟ್ನಲ್ಲಿ `onClick` ಲಿಸನರ್ ಹೊಂದಿರುವ `div` ಇದ್ದರೆ, ಮತ್ತು ನೀವು ಆ `div` ನ ತಾರ್ಕಿಕ ಚೈಲ್ಡ್ ಆಗಿರುವ ಪೋರ್ಟಲ್ನೊಳಗೆ ಒಂದು ಬಟನ್ ಅನ್ನು ರೆಂಡರ್ ಮಾಡಿದರೆ, ಬಟನ್ ಅನ್ನು ಕ್ಲಿಕ್ ಮಾಡುವುದರಿಂದ ನೇಟಿವ್ DOM ಬಬ್ಲಿಂಗ್ ಮೂಲಕ `div` ನ `onClick` ಹ್ಯಾಂಡ್ಲರ್ ಅನ್ನು ಟ್ರಿಗರ್ ಮಾಡುವುದಿಲ್ಲ.
ಆದಾಗ್ಯೂ, ಮತ್ತು ಇದು ಒಂದು ನಿರ್ಣಾಯಕ ವ್ಯತ್ಯಾಸ: ರಿಯಾಕ್ಟ್ನ ಸಿಂಥೆಟಿಕ್ ಈವೆಂಟ್ ಸಿಸ್ಟಮ್ ಈ ಅಂತರವನ್ನು ಸೇತುವೆಯಾಗಿ ನಿರ್ಮಿಸುತ್ತದೆ. ಪೋರ್ಟಲ್ನಿಂದ ನೇಟಿವ್ ಈವೆಂಟ್ ಹುಟ್ಟಿದಾಗ, ರಿಯಾಕ್ಟ್ನ ಆಂತರಿಕ ಯಾಂತ್ರಿಕತೆಯು ಸಿಂಥೆಟಿಕ್ ಈವೆಂಟ್ ಇನ್ನೂ ರಿಯಾಕ್ಟ್ ಕಾಂಪೊನೆಂಟ್ ಟ್ರೀಯ ಮೂಲಕ ತಾರ್ಕಿಕ ಪೋಷಕರಿಗೆ ಬಬಲ್ ಆಗುವುದನ್ನು ಖಚಿತಪಡಿಸುತ್ತದೆ. ಇದರರ್ಥ, ತಾರ್ಕಿಕವಾಗಿ ಪೋರ್ಟಲ್ ಅನ್ನು ಒಳಗೊಂಡಿರುವ ರಿಯಾಕ್ಟ್ ಕಾಂಪೊನೆಂಟ್ನಲ್ಲಿ `onClick` ಹ್ಯಾಂಡ್ಲರ್ ಇದ್ದರೆ, ಪೋರ್ಟಲ್ನೊಳಗಿನ ಕ್ಲಿಕ್ ಆ ಹ್ಯಾಂಡ್ಲರ್ ಅನ್ನು *ಟ್ರಿಗರ್ ಮಾಡುತ್ತದೆ*. ಇದು ರಿಯಾಕ್ಟ್ನ ಈವೆಂಟ್ ಸಿಸ್ಟಮ್ನ ಒಂದು ಮೂಲಭೂತ ಅಂಶವಾಗಿದ್ದು, ಇದು ಪೋರ್ಟಲ್ಗಳೊಂದಿಗೆ ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಅನ್ನು ಸಾಧ್ಯವಾಗಿಸುವುದಲ್ಲದೆ, ಶಿಫಾರಸು ಮಾಡಲಾದ ವಿಧಾನವನ್ನಾಗಿಯೂ ಮಾಡುತ್ತದೆ.
ಪರಿಹಾರ: ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ವಿವರವಾಗಿ
ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಎನ್ನುವುದು ಈವೆಂಟ್ಗಳನ್ನು ನಿಭಾಯಿಸಲು ಒಂದು ವಿನ್ಯಾಸ ಮಾದರಿಯಾಗಿದೆ, ಇದರಲ್ಲಿ ನೀವು ಬಹು ಡಿಸೆಂಡೆಂಟ್ ಎಲಿಮೆಂಟ್ಗಳಿಗೆ ಪ್ರತ್ಯೇಕ ಲಿಸನರ್ಗಳನ್ನು ಲಗತ್ತಿಸುವ ಬದಲು, ಸಾಮಾನ್ಯ ಪೂರ್ವಜ ಎಲಿಮೆಂಟ್ಗೆ ಒಂದೇ ಈವೆಂಟ್ ಲಿಸನರ್ ಅನ್ನು ಲಗತ್ತಿಸುತ್ತೀರಿ. ಡಿಸೆಂಡೆಂಟ್ ಮೇಲೆ ಒಂದು ಈವೆಂಟ್ (ಕ್ಲಿಕ್ನಂತಹ) ಸಂಭವಿಸಿದಾಗ, ಅದು DOM ಟ್ರೀಯ ಮೂಲಕ ಬಬಲ್ ಆಗಿ ಡೆಲಿಗೇಟೆಡ್ ಲಿಸನರ್ ಇರುವ ಪೂರ್ವಜನನ್ನು ತಲುಪುತ್ತದೆ. ನಂತರ ಲಿಸನರ್ `event.target` ಗುಣಲಕ್ಷಣವನ್ನು ಬಳಸಿ ಈವೆಂಟ್ ಹುಟ್ಟಿದ ನಿರ್ದಿಷ್ಟ ಎಲಿಮೆಂಟ್ ಅನ್ನು ಗುರುತಿಸುತ್ತದೆ ಮತ್ತು ಅದಕ್ಕೆ ತಕ್ಕಂತೆ ಪ್ರತಿಕ್ರಿಯಿಸುತ್ತದೆ.
ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ನ ಪ್ರಮುಖ ಅನುಕೂಲಗಳು
- ಕಾರ್ಯಕ್ಷಮತೆ ಆಪ್ಟಿಮೈಸೇಶನ್: ಹಲವಾರು ಈವೆಂಟ್ ಲಿಸನರ್ಗಳ ಬದಲು, ನಿಮ್ಮ ಬಳಿ ಒಂದೇ ಒಂದು ಇರುತ್ತದೆ. ಇದು ಮೆಮೊರಿ ಬಳಕೆ ಮತ್ತು ಸೆಟಪ್ ಸಮಯವನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ, ವಿಶೇಷವಾಗಿ ಅನೇಕ ಸಂವಾದಾತ್ಮಕ ಎಲಿಮೆಂಟ್ಗಳನ್ನು ಹೊಂದಿರುವ ಸಂಕೀರ್ಣ UI ಗಳಿಗೆ ಅಥವಾ ಸಂಪನ್ಮೂಲ ದಕ್ಷತೆಯು ಅತ್ಯಗತ್ಯವಾಗಿರುವ ಜಾಗತಿಕವಾಗಿ ನಿಯೋಜಿಸಲಾದ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ ಪ್ರಯೋಜನಕಾರಿಯಾಗಿದೆ.
- ಡೈನಾಮಿಕ್ ಕಂಟೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್: ಆರಂಭಿಕ ರೆಂಡರ್ ನಂತರ DOM ಗೆ ಸೇರಿಸಲಾದ ಎಲಿಮೆಂಟ್ಗಳು (ಉದಾ., AJAX ವಿನಂತಿಗಳು ಅಥವಾ ಬಳಕೆದಾರರ ಸಂವಹನಗಳ ಮೂಲಕ) ಹೊಸ ಲಿಸನರ್ಗಳನ್ನು ಲಗತ್ತಿಸುವ ಅಗತ್ಯವಿಲ್ಲದೆ ಡೆಲಿಗೇಟೆಡ್ ಲಿಸನರ್ಗಳಿಂದ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಪ್ರಯೋಜನ ಪಡೆಯುತ್ತವೆ. ಇದು ಡೈನಾಮಿಕ್ ಆಗಿ ರೆಂಡರ್ ಆದ ಪೋರ್ಟಲ್ ಕಂಟೆಂಟ್ಗೆ ಸಂಪೂರ್ಣವಾಗಿ ಸೂಕ್ತವಾಗಿದೆ.
- ಕ್ಲೀನರ್ ಕೋಡ್: ಈವೆಂಟ್ ತರ್ಕವನ್ನು ಕೇಂದ್ರೀಕರಿಸುವುದು ನಿಮ್ಮ ಕೋಡ್ಬೇಸ್ ಅನ್ನು ಹೆಚ್ಚು ಸಂಘಟಿತ ಮತ್ತು ನಿರ್ವಹಿಸಲು ಸುಲಭವಾಗಿಸುತ್ತದೆ.
- DOM ರಚನೆಗಳಾದ್ಯಂತ ದೃಢತೆ: ನಾವು ಚರ್ಚಿಸಿದಂತೆ, ರಿಯಾಕ್ಟ್ನ ಸಿಂಥೆಟಿಕ್ ಈವೆಂಟ್ ಸಿಸ್ಟಮ್ ಪೋರ್ಟಲ್ನ ಕಂಟೆಂಟ್ನಿಂದ ಹುಟ್ಟುವ ಈವೆಂಟ್ಗಳು *ಇನ್ನೂ* ರಿಯಾಕ್ಟ್ ಕಾಂಪೊನೆಂಟ್ ಟ್ರೀಯ ಮೂಲಕ ಅವುಗಳ ತಾರ್ಕಿಕ ಪೂರ್ವಜರಿಗೆ ಬಬಲ್ ಆಗುವುದನ್ನು ಖಚಿತಪಡಿಸುತ್ತದೆ. ಇದು ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಅನ್ನು ಪೋರ್ಟಲ್ಗಳಿಗೆ ಪರಿಣಾಮಕಾರಿ ತಂತ್ರವನ್ನಾಗಿಸುವ ಮೂಲಾಧಾರವಾಗಿದೆ, ಅವುಗಳ ಭೌತಿಕ DOM ಸ್ಥಳವು ಭಿನ್ನವಾಗಿದ್ದರೂ ಸಹ.
ಈವೆಂಟ್ ಬಬ್ಲಿಂಗ್ ಮತ್ತು ಕ್ಯಾಪ್ಚರಿಂಗ್ ವಿವರಿಸಲಾಗಿದೆ
ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಅನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ಗ್ರಹಿಸಲು, DOM ನಲ್ಲಿ ಈವೆಂಟ್ ಪ್ರಸರಣದ ಎರಡು ಹಂತಗಳನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು ನಿರ್ಣಾಯಕವಾಗಿದೆ:
- ಕ್ಯಾಪ್ಚರಿಂಗ್ ಹಂತ (ಟ್ರಿಕಲ್ ಡೌನ್): ಈವೆಂಟ್ `document` ರೂಟ್ನಲ್ಲಿ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ ಮತ್ತು DOM ಟ್ರೀಯ ಕೆಳಗೆ ಪ್ರಯಾಣಿಸುತ್ತದೆ, ಟಾರ್ಗೆಟ್ ಎಲಿಮೆಂಟ್ ಅನ್ನು ತಲುಪುವವರೆಗೆ ಪ್ರತಿ ಪೂರ್ವಜ ಎಲಿಮೆಂಟ್ ಅನ್ನು ಭೇಟಿ ಮಾಡುತ್ತದೆ. `useCapture = true` (ಅಥವಾ ರಿಯಾಕ್ಟ್ನಲ್ಲಿ, `Capture` ಪ್ರತ್ಯಯವನ್ನು ಸೇರಿಸುವ ಮೂಲಕ, ಉದಾ., `onClickCapture`) ನೊಂದಿಗೆ ನೋಂದಾಯಿಸಲಾದ ಲಿಸನರ್ಗಳು ಈ ಹಂತದಲ್ಲಿ ಫೈರ್ ಆಗುತ್ತವೆ.
- ಬಬ್ಲಿಂಗ್ ಹಂತ (ಬಬಲ್ ಅಪ್): ಟಾರ್ಗೆಟ್ ಎಲಿಮೆಂಟ್ ಅನ್ನು ತಲುಪಿದ ನಂತರ, ಈವೆಂಟ್ ನಂತರ DOM ಟ್ರೀಯ ಮೇಲಕ್ಕೆ ಹಿಂತಿರುಗುತ್ತದೆ, ಟಾರ್ಗೆಟ್ ಎಲಿಮೆಂಟ್ನಿಂದ `document` ರೂಟ್ಗೆ, ಪ್ರತಿ ಪೂರ್ವಜ ಎಲಿಮೆಂಟ್ ಅನ್ನು ಭೇಟಿ ಮಾಡುತ್ತದೆ. ಹೆಚ್ಚಿನ ಈವೆಂಟ್ ಲಿಸನರ್ಗಳು, ಎಲ್ಲಾ ಪ್ರಮಾಣಿತ ರಿಯಾಕ್ಟ್ `onClick`, `onChange`, ಇತ್ಯಾದಿ ಸೇರಿದಂತೆ, ಈ ಹಂತದಲ್ಲಿ ಫೈರ್ ಆಗುತ್ತವೆ.
ರಿಯಾಕ್ಟ್ನ ಸಿಂಥೆಟಿಕ್ ಈವೆಂಟ್ ಸಿಸ್ಟಮ್ ಪ್ರಾಥಮಿಕವಾಗಿ ಬಬ್ಲಿಂಗ್ ಹಂತವನ್ನು ಅವಲಂಬಿಸಿದೆ. ಪೋರ್ಟಲ್ನೊಳಗಿನ ಎಲಿಮೆಂಟ್ನಲ್ಲಿ ಈವೆಂಟ್ ಸಂಭವಿಸಿದಾಗ, ನೇಟಿವ್ ಬ್ರೌಸರ್ ಈವೆಂಟ್ ಅದರ ಭೌತಿಕ DOM ಪಥದಲ್ಲಿ ಬಬಲ್ ಆಗುತ್ತದೆ. ರಿಯಾಕ್ಟ್ನ ರೂಟ್ ಲಿಸನರ್ (ಸಾಮಾನ್ಯವಾಗಿ `document` ನಲ್ಲಿ) ಈ ನೇಟಿವ್ ಈವೆಂಟ್ ಅನ್ನು ಹಿಡಿಯುತ್ತದೆ. ನಿರ್ಣಾಯಕವಾಗಿ, ರಿಯಾಕ್ಟ್ ನಂತರ ಈವೆಂಟ್ ಅನ್ನು ಪುನರ್ನಿರ್ಮಿಸುತ್ತದೆ ಮತ್ತು ಅದರ *ಸಿಂಥೆಟಿಕ್* ಪ್ರತಿರೂಪವನ್ನು ರವಾನಿಸುತ್ತದೆ, ಇದು ಪೋರ್ಟಲ್ನೊಳಗಿನ ಕಾಂಪೊನೆಂಟ್ನಿಂದ ಅದರ ತಾರ್ಕಿಕ ಪೋಷಕ ಕಾಂಪೊನೆಂಟ್ಗೆ *ರಿಯಾಕ್ಟ್ ಕಾಂಪೊನೆಂಟ್ ಟ್ರೀಯ ಮೂಲಕ ಬಬ್ಲಿಂಗ್ ಅನ್ನು ಅನುಕರಿಸುತ್ತದೆ*. ಈ ಬುದ್ಧಿವಂತ ಅಮೂರ್ತತೆಯು ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಪೋರ್ಟಲ್ಗಳೊಂದಿಗೆ, ಅವುಗಳ ಪ್ರತ್ಯೇಕ ಭೌತಿಕ DOM ಉಪಸ್ಥಿತಿಯ ಹೊರತಾಗಿಯೂ, ಮನಬಂದಂತೆ ಕೆಲಸ ಮಾಡುವುದನ್ನು ಖಚಿತಪಡಿಸುತ್ತದೆ.
ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ಗಳೊಂದಿಗೆ ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದು
ಬಳಕೆದಾರರು ಅದರ ಕಂಟೆಂಟ್ ಪ್ರದೇಶದ ಹೊರಗೆ (ಬ್ಯಾಕ್ಡ್ರಾಪ್ನಲ್ಲಿ) ಕ್ಲಿಕ್ ಮಾಡಿದಾಗ ಅಥವಾ `Escape` ಕೀಲಿಯನ್ನು ಒತ್ತಿದಾಗ ಮುಚ್ಚುವ ಮೋಡಲ್ ಡೈಲಾಗ್ ಎಂಬ ಸಾಮಾನ್ಯ ಸನ್ನಿವೇಶವನ್ನು ನೋಡೋಣ. ಇದು ಪೋರ್ಟಲ್ಗಳಿಗೆ ಒಂದು ಕ್ಲಾಸಿಕ್ ಬಳಕೆಯಾಗಿದೆ ಮತ್ತು ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ನ ಅತ್ಯುತ್ತಮ ಪ್ರದರ್ಶನವಾಗಿದೆ.
ಸನ್ನಿವೇಶ: ಹೊರಗೆ ಕ್ಲಿಕ್ ಮಾಡಿದರೆ-ಮುಚ್ಚುವ ಮೋಡಲ್
ನಾವು ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ ಬಳಸಿ ಒಂದು ಮೋಡಲ್ ಕಾಂಪೊನೆಂಟ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಬಯಸುತ್ತೇವೆ. ಒಂದು ಬಟನ್ ಕ್ಲಿಕ್ ಮಾಡಿದಾಗ ಮೋಡಲ್ ಕಾಣಿಸಿಕೊಳ್ಳಬೇಕು, ಮತ್ತು ಅದು ಮುಚ್ಚಬೇಕು ಯಾವಾಗ:
- ಬಳಕೆದಾರರು ಮೋಡಲ್ ಕಂಟೆಂಟ್ ಅನ್ನು ಸುತ್ತುವರೆದಿರುವ ಅರೆ-ಪಾರದರ್ಶಕ ಓವರ್ಲೇ (ಬ್ಯಾಕ್ಡ್ರಾಪ್) ಮೇಲೆ ಕ್ಲಿಕ್ ಮಾಡಿದಾಗ.
- ಬಳಕೆದಾರರು `Escape` ಕೀಲಿಯನ್ನು ಒತ್ತಿದಾಗ.
- ಬಳಕೆದಾರರು ಮೋಡಲ್ನೊಳಗಿನ ಸ್ಪಷ್ಟವಾದ "Close" ಬಟನ್ ಅನ್ನು ಕ್ಲಿಕ್ ಮಾಡಿದಾಗ.
ಹಂತ-ಹಂತದ ಅನುಷ್ಠಾನ
ಹಂತ 1: HTML ಮತ್ತು ಪೋರ್ಟಲ್ ಕಾಂಪೊನೆಂಟ್ ಅನ್ನು ಸಿದ್ಧಪಡಿಸಿ
ನಿಮ್ಮ `index.html` ಪೋರ್ಟಲ್ಗಳಿಗೆ ಮೀಸಲಾದ ರೂಟ್ ಅನ್ನು ಹೊಂದಿದೆ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ. ಈ ಉದಾಹರಣೆಗಾಗಿ, `id="portal-root"` ಅನ್ನು ಬಳಸೋಣ.
// public/index.html (ಸಣ್ಣ ತುಣುಕು)
<body>
<div id="root"></div>
<div id="portal-root"></div> <!-- ನಮ್ಮ ಪೋರ್ಟಲ್ ಟಾರ್ಗೆಟ್ -->
</body>
ಮುಂದೆ, `ReactDOM.createPortal` ತರ್ಕವನ್ನು ಆವರಿಸಲು ಒಂದು ಸರಳ `Portal` ಕಾಂಪೊನೆಂಟ್ ಅನ್ನು ರಚಿಸಿ. ಇದು ನಮ್ಮ ಮೋಡಲ್ ಕಾಂಪೊನೆಂಟ್ ಅನ್ನು ಸ್ವಚ್ಛವಾಗಿಸುತ್ತದೆ.
// components/Portal.js
import { useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
interface PortalProps {
children: React.ReactNode;
wrapperId?: string;
}
// wrapperId ಗಾಗಿ ಈಗಾಗಲೇ ಪೋರ್ಟಲ್ಗೆ ಡಿವ್ ಅಸ್ತಿತ್ವದಲ್ಲಿಲ್ಲದಿದ್ದರೆ ನಾವು ಒಂದನ್ನು ರಚಿಸುತ್ತೇವೆ
function createWrapperAndAppendToBody(wrapperId: string) {
const wrapperElement = document.createElement('div');
wrapperElement.setAttribute('id', wrapperId);
document.body.appendChild(wrapperElement);
return wrapperElement;
}
function Portal({ children, wrapperId = 'portal-wrapper' }: PortalProps) {
const [wrapperElement, setWrapperElement] = useState<HTMLElement | null>(null);
useEffect(() => {
let element = document.getElementById(wrapperId) as HTMLElement;
let created = false;
if (!element) {
created = true;
element = createWrapperAndAppendToBody(wrapperId);
}
setWrapperElement(element);
return () => {
// ನಾವು ಎಲಿಮೆಂಟ್ ಅನ್ನು ರಚಿಸಿದ್ದರೆ ಅದನ್ನು ಕ್ಲೀನ್ ಅಪ್ ಮಾಡಿ
if (created && element.parentNode) {
element.parentNode.removeChild(element);
}
};
}, [wrapperId]);
// ಮೊದಲ ರೆಂಡರ್ನಲ್ಲಿ wrapperElement ಶೂನ್ಯವಾಗಿರುತ್ತದೆ. ಇದು ಸರಿಯಾಗಿದೆ ಏಕೆಂದರೆ ನಾವು ಏನನ್ನೂ ರೆಂಡರ್ ಮಾಡುವುದಿಲ್ಲ.
if (!wrapperElement) return null;
return createPortal(children, wrapperElement);
}
export default Portal;
ಗಮನಿಸಿ: ಸರಳತೆಗಾಗಿ, ಹಿಂದಿನ ಉದಾಹರಣೆಗಳಲ್ಲಿ `portal-root` ಅನ್ನು `index.html` ನಲ್ಲಿ ಹಾರ್ಡ್ಕೋಡ್ ಮಾಡಲಾಗಿತ್ತು. ಈ `Portal.js` ಕಾಂಪೊನೆಂಟ್ ಒಂದು ಹೆಚ್ಚು ಡೈನಾಮಿಕ್ ವಿಧಾನವನ್ನು ನೀಡುತ್ತದೆ, ಒಂದು ವ್ರ್ಯಾಪರ್ ಡಿವ್ ಅಸ್ತಿತ್ವದಲ್ಲಿಲ್ಲದಿದ್ದರೆ ಅದನ್ನು ರಚಿಸುತ್ತದೆ. ನಿಮ್ಮ ಪ್ರಾಜೆಕ್ಟ್ನ ಅಗತ್ಯಗಳಿಗೆ ಸೂಕ್ತವಾದ ವಿಧಾನವನ್ನು ಆರಿಸಿ. ನಾವು ನೇರತೆಗಾಗಿ `Modal` ಕಾಂಪೊನೆಂಟ್ಗೆ `index.html` ನಲ್ಲಿ ನಿರ್ದಿಷ್ಟಪಡಿಸಿದ `portal-root` ಅನ್ನು ಬಳಸಿಕೊಂಡು ಮುಂದುವರಿಯುತ್ತೇವೆ, ಆದರೆ ಮೇಲಿನ `Portal.js` ಒಂದು ದೃಢವಾದ ಪರ್ಯಾಯವಾಗಿದೆ.
ಹಂತ 2: ಮೋಡಲ್ ಕಾಂಪೊನೆಂಟ್ ರಚಿಸಿ
ನಮ್ಮ `Modal` ಕಾಂಪೊನೆಂಟ್ ತನ್ನ ಕಂಟೆಂಟ್ ಅನ್ನು `children` ಆಗಿ ಮತ್ತು `onClose` ಕಾಲ್ಬ್ಯಾಕ್ ಅನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ.
// components/Modal.js
import React, { useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
interface ModalProps {
isOpen: boolean;
onClose: () => void;
children: React.ReactNode;
}
const modalRoot = document.getElementById('portal-root') as HTMLElement;
const Modal = ({ isOpen, onClose, children }: ModalProps) => {
const modalContentRef = useRef<HTMLDivElement>(null);
if (!isOpen) return null;
// Escape ಕೀ ಒತ್ತಡವನ್ನು ನಿಭಾಯಿಸಿ
useEffect(() => {
const handleEscape = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
onClose();
}
};
document.addEventListener('keydown', handleEscape);
return () => {
document.removeEventListener('keydown', handleEscape);
};
}, [onClose]);
// ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ಗೆ ಕೀ: ಬ್ಯಾಕ್ಡ್ರಾಪ್ನಲ್ಲಿ ಒಂದೇ ಕ್ಲಿಕ್ ಹ್ಯಾಂಡ್ಲರ್.
// ಇದು ಮೋಡಲ್ನೊಳಗಿನ ಕ್ಲೋಸ್ ಬಟನ್ಗೆ ಪರೋಕ್ಷವಾಗಿ ಡೆಲಿಗೇಟ್ ಮಾಡುತ್ತದೆ.
const handleBackdropClick = (event: React.MouseEvent<HTMLDivElement>) => {
// ಕ್ಲಿಕ್ ಟಾರ್ಗೆಟ್ ಬ್ಯಾಕ್ಡ್ರಾಪ್ ಆಗಿದೆಯೇ ಹೊರತು ಮೋಡಲ್ನೊಳಗಿನ ಕಂಟೆಂಟ್ ಅಲ್ಲವೇ ಎಂದು ಪರಿಶೀಲಿಸಿ.
// ಇಲ್ಲಿ `modalContentRef.current.contains(event.target)` ಬಳಸುವುದು ನಿರ್ಣಾಯಕವಾಗಿದೆ.
// event.target ಕ್ಲಿಕ್ ಅನ್ನು ಹುಟ್ಟುಹಾಕಿದ ಎಲಿಮೆಂಟ್ ಆಗಿದೆ.
// event.currentTarget ಎನ್ನುವುದು ಈವೆಂಟ್ ಲಿಸನರ್ ಅನ್ನು ಲಗತ್ತಿಸಲಾದ ಎಲಿಮೆಂಟ್ ಆಗಿದೆ (modal-overlay).
if (modalContentRef.current && !modalContentRef.current.contains(event.target as Node)) {
onClose();
}
};
return ReactDOM.createPortal(
<div className="modal-overlay" onClick={handleBackdropClick}>
<div className="modal-content" ref={modalContentRef}>
{children}
<button onClick={onClose} aria-label="Close modal">X</button>
</div>
</div>,
modalRoot
);
};
export default Modal;
ಹಂತ 3: ಮುಖ್ಯ ಅಪ್ಲಿಕೇಶನ್ ಕಾಂಪೊನೆಂಟ್ಗೆ ಸಂಯೋಜಿಸಿ
ನಮ್ಮ ಮುಖ್ಯ `App` ಕಾಂಪೊನೆಂಟ್ ಮೋಡಲ್ನ ತೆರೆಯುವ/ಮುಚ್ಚುವ ಸ್ಥಿತಿಯನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು `Modal` ಅನ್ನು ರೆಂಡರ್ ಮಾಡುತ್ತದೆ.
// App.js
import React, { useState } from 'react';
import Modal from './components/Modal';
import './App.css'; // ಮೂಲಭೂತ ಸ್ಟೈಲಿಂಗ್ಗಾಗಿ
function App() {
const [isModalOpen, setIsModalOpen] = useState(false);
const openModal = () => setIsModalOpen(true);
const closeModal = () => setIsModalOpen(false);
return (
<div className="App">
<h1>ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಉದಾಹರಣೆ</h1>
<p>ವಿವಿಧ DOM ಟ್ರೀಗಳಾದ್ಯಂತ ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್ ಅನ್ನು ಪ್ರದರ್ಶಿಸುವುದು.</p>
<button onClick={openModal}>ಮೋಡಲ್ ತೆರೆಯಿರಿ</button>
<Modal isOpen={isModalOpen} onClose={closeModal}>
<h2>ಮೋಡಲ್ಗೆ ಸ್ವಾಗತ!</h2>
<p>ಈ ಕಂಟೆಂಟ್ ಅನ್ನು ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ನಲ್ಲಿ ರೆಂಡರ್ ಮಾಡಲಾಗಿದೆ, ಇದು ಮುಖ್ಯ ಅಪ್ಲಿಕೇಶನ್ನ DOM ಶ್ರೇಣಿಯ ಹೊರಗಿದೆ.</p>
<button onClick={closeModal}>ಒಳಗಿನಿಂದ ಮುಚ್ಚಿ</button>
</Modal>
<p>ಮೋಡಲ್ನ ಹಿಂದೆ ಇರುವ ಇತರ ಕಂಟೆಂಟ್.</p>
<p>ಹಿನ್ನೆಲೆಯನ್ನು ತೋರಿಸಲು ಮತ್ತೊಂದು ಪ್ಯಾರಾಗ್ರಾಫ್.</p>
</div>
);
}
export default App;
ಹಂತ 4: ಮೂಲಭೂತ ಸ್ಟೈಲಿಂಗ್ (App.css)
ಮೋಡಲ್ ಮತ್ತು ಅದರ ಬ್ಯಾಕ್ಡ್ರಾಪ್ ಅನ್ನು ದೃಶ್ಯೀಕರಿಸಲು.
/* App.css */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-content {
background: white;
padding: 30px;
border-radius: 8px;
min-width: 300px;
max-width: 80%;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
position: relative; /* Needed for internal button positioning if any */
}
.modal-content button {
margin-top: 15px;
padding: 8px 15px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
}
.modal-content button:hover {
background-color: #0056b3;
}
.modal-content > button:last-child { /* 'X' ಕ್ಲೋಸ್ ಬಟನ್ಗಾಗಿ ಶೈಲಿ */
position: absolute;
top: 10px;
right: 10px;
background: none;
color: #333;
font-size: 1.2rem;
padding: 0;
margin: 0;
border: none;
}
.App {
font-family: Arial, sans-serif;
padding: 20px;
text-align: center;
}
.App button {
padding: 10px 20px;
font-size: 1.1rem;
background-color: #28a745;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.App button:hover {
background-color: #218838;
}
ಡೆಲಿಗೇಷನ್ ತರ್ಕದ ವಿವರಣೆ
ನಮ್ಮ `Modal` ಕಾಂಪೊನೆಂಟ್ನಲ್ಲಿ, `onClick={handleBackdropClick}` ಅನ್ನು `.modal-overlay` ಡಿವ್ಗೆ ಲಗತ್ತಿಸಲಾಗಿದೆ, ಇದು ನಮ್ಮ ಡೆಲಿಗೇಟೆಡ್ ಲಿಸನರ್ ಆಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ. ಈ ಓವರ್ಲೇಯೊಳಗೆ ಯಾವುದೇ ಕ್ಲಿಕ್ ಸಂಭವಿಸಿದಾಗ (ಇದು `modal-content` ಮತ್ತು ಅದರೊಳಗಿನ `X` ಕ್ಲೋಸ್ ಬಟನ್, ಹಾಗೆಯೇ 'Close from inside' ಬಟನ್ ಅನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ), `handleBackdropClick` ಫಂಕ್ಷನ್ ಕಾರ್ಯಗತಗೊಳ್ಳುತ್ತದೆ.
`handleBackdropClick` ಒಳಗೆ:
- `event.target` *ನಿಜವಾಗಿ ಕ್ಲಿಕ್ ಮಾಡಿದ* ನಿರ್ದಿಷ್ಟ DOM ಎಲಿಮೆಂಟ್ ಅನ್ನು ಸೂಚಿಸುತ್ತದೆ (ಉದಾ., `modal-content` ಒಳಗೆ `<h2>`, `<p>`, ಅಥವಾ `<button>`, ಅಥವಾ `modal-overlay` ಸ್ವತಃ).
- `event.currentTarget` ಈವೆಂಟ್ ಲಿಸನರ್ ಅನ್ನು ಲಗತ್ತಿಸಲಾದ ಎಲಿಮೆಂಟ್ ಅನ್ನು ಸೂಚಿಸುತ್ತದೆ, ಈ ಸಂದರ್ಭದಲ್ಲಿ ಅದು `.modal-overlay` ಡಿವ್ ಆಗಿದೆ.
- `!modalContentRef.current.contains(event.target as Node)` ಎಂಬ ಷರತ್ತು ನಮ್ಮ ಡೆಲಿಗೇಷನ್ನ ಹೃದಯವಾಗಿದೆ. ಇದು ಕ್ಲಿಕ್ ಮಾಡಿದ ಎಲಿಮೆಂಟ್ (`event.target`) `modal-content` ಡಿವ್ನ ಡಿಸೆಂಡೆಂಟ್ *ಅಲ್ಲವೇ* ಎಂದು ಪರಿಶೀಲಿಸುತ್ತದೆ. `event.target` `.modal-overlay` ಆಗಿದ್ದರೆ, ಅಥವಾ ಓವರ್ಲೇಯ ನೇರ ಚೈಲ್ಡ್ ಆಗಿದ್ದು `modal-content` ನ ಭಾಗವಾಗಿರದ ಯಾವುದೇ ಇತರ ಎಲಿಮೆಂಟ್ ಆಗಿದ್ದರೆ, `contains` `false` ಅನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ, ಮತ್ತು ಮೋಡಲ್ ಮುಚ್ಚುತ್ತದೆ.
- ನಿರ್ಣಾಯಕವಾಗಿ, ರಿಯಾಕ್ಟ್ನ ಸಿಂಥೆಟಿಕ್ ಈವೆಂಟ್ ಸಿಸ್ಟಮ್, `event.target` `portal-root` ನಲ್ಲಿ ಭೌತಿಕವಾಗಿ ರೆಂಡರ್ ಆದ ಎಲಿಮೆಂಟ್ ಆಗಿದ್ದರೂ ಸಹ, ತಾರ್ಕಿಕ ಪೋಷಕ (`Modal` ಕಾಂಪೊನೆಂಟ್ನಲ್ಲಿನ `.modal-overlay`) ಮೇಲಿನ `onClick` ಹ್ಯಾಂಡ್ಲರ್ ಇನ್ನೂ ಟ್ರಿಗರ್ ಆಗುತ್ತದೆ ಮತ್ತು `event.target` ಆಳವಾಗಿ ನೆಸ್ಟೆಡ್ ಎಲಿಮೆಂಟ್ ಅನ್ನು ಸರಿಯಾಗಿ ಗುರುತಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸುತ್ತದೆ.
ಆಂತರಿಕ ಕ್ಲೋಸ್ ಬಟನ್ಗಳಿಗೆ, ಅವುಗಳ `onClick` ಹ್ಯಾಂಡ್ಲರ್ಗಳಲ್ಲಿ ನೇರವಾಗಿ `onClose()` ಅನ್ನು ಕರೆಯುವುದು ಕೆಲಸ ಮಾಡುತ್ತದೆ ಏಕೆಂದರೆ ಈ ಹ್ಯಾಂಡ್ಲರ್ಗಳು ಈವೆಂಟ್ `modal-overlay` ನ ಡೆಲಿಗೇಟೆಡ್ ಲಿಸನರ್ಗೆ ಬಬಲ್ ಆಗುವ *ಮೊದಲು* ಕಾರ್ಯಗತಗೊಳ್ಳುತ್ತವೆ, ಅಥವಾ ಅವುಗಳನ್ನು ಸ್ಪಷ್ಟವಾಗಿ ನಿಭಾಯಿಸಲಾಗುತ್ತದೆ. ಅವು ಬಬಲ್ ಆದರೂ, ನಮ್ಮ `contains()` ಪರಿಶೀಲನೆಯು ಕ್ಲಿಕ್ ಕಂಟೆಂಟ್ನ ಒಳಗಿನಿಂದ ಹುಟ್ಟಿದ್ದರೆ ಮೋಡಲ್ ಮುಚ್ಚುವುದನ್ನು ತಡೆಯುತ್ತದೆ.
`Escape` ಕೀ ಲಿಸನರ್ಗಾಗಿ `useEffect` ಅನ್ನು ನೇರವಾಗಿ `document` ಗೆ ಲಗತ್ತಿಸಲಾಗಿದೆ, ಇದು ಜಾಗತಿಕ ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್ಕಟ್ಗಳಿಗೆ ಸಾಮಾನ್ಯ ಮತ್ತು ಪರಿಣಾಮಕಾರಿ ಮಾದರಿಯಾಗಿದೆ, ಏಕೆಂದರೆ ಇದು ಕಾಂಪೊನೆಂಟ್ ಫೋಕಸ್ ಅನ್ನು ಲೆಕ್ಕಿಸದೆ ಲಿಸನರ್ ಸಕ್ರಿಯವಾಗಿರುವುದನ್ನು ಖಚಿತಪಡಿಸುತ್ತದೆ, ಮತ್ತು ಇದು ಪೋರ್ಟಲ್ಗಳ ಒಳಗಿನಿಂದ ಹುಟ್ಟುವ ಈವೆಂಟ್ಗಳನ್ನು ಒಳಗೊಂಡಂತೆ DOM ನಲ್ಲಿ ಎಲ್ಲಿಂದಲಾದರೂ ಈವೆಂಟ್ಗಳನ್ನು ಹಿಡಿಯುತ್ತದೆ.
ಸಾಮಾನ್ಯ ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಸನ್ನಿವೇಶಗಳನ್ನು ಪರಿಹರಿಸುವುದು
ಅನಗತ್ಯ ಈವೆಂಟ್ ಪ್ರಸರಣವನ್ನು ತಡೆಯುವುದು: `event.stopPropagation()`
ಕೆಲವೊಮ್ಮೆ, ಡೆಲಿಗೇಷನ್ನೊಂದಿಗೆ ಸಹ, ನಿಮ್ಮ ಡೆಲಿಗೇಟೆಡ್ ಪ್ರದೇಶದೊಳಗೆ ನೀವು ನಿರ್ದಿಷ್ಟ ಎಲಿಮೆಂಟ್ಗಳನ್ನು ಹೊಂದಿರಬಹುದು, ಅಲ್ಲಿ ನೀವು ಈವೆಂಟ್ ಅನ್ನು ಮತ್ತಷ್ಟು ಮೇಲಕ್ಕೆ ಬಬಲ್ ಆಗದಂತೆ ಸ್ಪಷ್ಟವಾಗಿ ನಿಲ್ಲಿಸಲು ಬಯಸುತ್ತೀರಿ. ಉದಾಹರಣೆಗೆ, ನಿಮ್ಮ ಮೋಡಲ್ ಕಂಟೆಂಟ್ನೊಳಗೆ ನೆಸ್ಟೆಡ್ ಸಂವಾದಾತ್ಮಕ ಎಲಿಮೆಂಟ್ ಇದ್ದರೆ, ಅದನ್ನು ಕ್ಲಿಕ್ ಮಾಡಿದಾಗ `onClose` ತರ್ಕವನ್ನು ಟ್ರಿಗರ್ ಮಾಡಬಾರದು (`contains` ಪರಿಶೀಲನೆಯು ಈಗಾಗಲೇ ಅದನ್ನು ನಿಭಾಯಿಸುತ್ತಿದ್ದರೂ), ನೀವು `event.stopPropagation()` ಅನ್ನು ಬಳಸಬಹುದು.
<div className="modal-content" ref={modalContentRef}>
<h2>ಮೋಡಲ್ ಕಂಟೆಂಟ್</h2>
<p>ಈ ಪ್ರದೇಶವನ್ನು ಕ್ಲಿಕ್ ಮಾಡುವುದರಿಂದ ಮೋಡಲ್ ಮುಚ್ಚುವುದಿಲ್ಲ.</p>
<button onClick={(e) => {
e.stopPropagation(); // ಈ ಕ್ಲಿಕ್ ಅನ್ನು ಬ್ಯಾಕ್ಡ್ರಾಪ್ಗೆ ಬಬಲ್ ಆಗದಂತೆ ತಡೆಯಿರಿ
console.log('ಒಳಗಿನ ಬಟನ್ ಕ್ಲಿಕ್ ಮಾಡಲಾಗಿದೆ!');
}}>ಒಳಗಿನ ಆಕ್ಷನ್ ಬಟನ್</button>
<button onClick={onClose}>ಮುಚ್ಚಿ</button>
</div>
`event.stopPropagation()` ಉಪಯುಕ್ತವಾಗಿದ್ದರೂ, ಅದನ್ನು ವಿವೇಚನೆಯಿಂದ ಬಳಸಿ. ಅತಿಯಾದ ಬಳಕೆಯು ಈವೆಂಟ್ ಹರಿವನ್ನು ಅನಿರೀಕ್ಷಿತವಾಗಿಸಬಹುದು ಮತ್ತು ಡೀಬಗ್ ಮಾಡುವುದನ್ನು ಕಷ್ಟಕರವಾಗಿಸಬಹುದು, ವಿಶೇಷವಾಗಿ ದೊಡ್ಡ, ಜಾಗತಿಕವಾಗಿ ವಿತರಿಸಲಾದ ಅಪ್ಲಿಕೇಶನ್ಗಳಲ್ಲಿ ವಿವಿಧ ತಂಡಗಳು UI ಗೆ ಕೊಡುಗೆ ನೀಡಬಹುದು.
ಡೆಲಿಗೇಷನ್ನೊಂದಿಗೆ ನಿರ್ದಿಷ್ಟ ಚೈಲ್ಡ್ ಎಲಿಮೆಂಟ್ಗಳನ್ನು ನಿಭಾಯಿಸುವುದು
ಕ್ಲಿಕ್ ಒಳಗೆ ಅಥವಾ ಹೊರಗೆ ಇದೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸುವುದನ್ನು ಮೀರಿ, ಡೆಲಿಗೇಟೆಡ್ ಪ್ರದೇಶದೊಳಗೆ ವಿವಿಧ ರೀತಿಯ ಕ್ಲಿಕ್ಗಳ ನಡುವೆ ವ್ಯತ್ಯಾಸವನ್ನು ಗುರುತಿಸಲು ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ನಿಮಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ವಿಭಿನ್ನ ಕ್ರಿಯೆಗಳನ್ನು ನಿರ್ವಹಿಸಲು ನೀವು `event.target.tagName`, `event.target.id`, `event.target.className`, ಅಥವಾ `event.target.dataset` ಗುಣಲಕ್ಷಣಗಳಂತಹ ಪ್ರಾಪರ್ಟಿಗಳನ್ನು ಬಳಸಬಹುದು.
const handleBackdropClick = (event: React.MouseEvent<HTMLDivElement>) => {
if (modalContentRef.current && modalContentRef.current.contains(event.target as Node)) {
// ಕ್ಲಿಕ್ ಮೋಡಲ್ ಕಂಟೆಂಟ್ನೊಳಗೆ ಇತ್ತು
const clickedElement = event.target as HTMLElement;
if (clickedElement.tagName === 'BUTTON' && clickedElement.dataset.action === 'confirm') {
console.log('ದೃಢೀಕರಣ ಕ್ರಿಯೆ ಟ್ರಿಗರ್ ಆಗಿದೆ!');
onClose();
} else if (clickedElement.tagName === 'A') {
console.log('ಮೋಡಲ್ನೊಳಗಿನ ಲಿಂಕ್ ಕ್ಲಿಕ್ ಮಾಡಲಾಗಿದೆ:', clickedElement.href);
// ಸಂಭಾವ್ಯವಾಗಿ ಡೀಫಾಲ್ಟ್ ವರ್ತನೆಯನ್ನು ತಡೆಯಿರಿ ಅಥವಾ ಪ್ರೋಗ್ರಾಮ್ಯಾಟಿಕ್ ಆಗಿ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ
}
// ಮೋಡಲ್ನೊಳಗಿನ ಎಲಿಮೆಂಟ್ಗಳಿಗಾಗಿ ಇತರ ನಿರ್ದಿಷ್ಟ ಹ್ಯಾಂಡ್ಲರ್ಗಳು
} else {
// ಕ್ಲಿಕ್ ಮೋಡಲ್ ಕಂಟೆಂಟ್ನ ಹೊರಗೆ ಇತ್ತು (ಬ್ಯಾಕ್ಡ್ರಾಪ್ನಲ್ಲಿ)
onClose();
}
};
ಈ ಮಾದರಿಯು ನಿಮ್ಮ ಪೋರ್ಟಲ್ ಕಂಟೆಂಟ್ನೊಳಗಿನ ಬಹು ಸಂವಾದಾತ್ಮಕ ಎಲಿಮೆಂಟ್ಗಳನ್ನು ಒಂದೇ, ಸಮರ್ಥ ಈವೆಂಟ್ ಲಿಸನರ್ ಬಳಸಿ ನಿರ್ವಹಿಸಲು ಒಂದು ಶಕ್ತಿಯುತ ಮಾರ್ಗವನ್ನು ಒದಗಿಸುತ್ತದೆ.
ಯಾವಾಗ ಡೆಲಿಗೇಟ್ ಮಾಡಬಾರದು
ಪೋರ್ಟಲ್ಗಳಿಗೆ ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಹೆಚ್ಚು ಶಿಫಾರಸು ಮಾಡಲಾಗಿದ್ದರೂ, ಎಲಿಮೆಂಟ್ನ ಮೇಲೆ ನೇರ ಈವೆಂಟ್ ಲಿಸನರ್ಗಳು ಹೆಚ್ಚು ಸೂಕ್ತವಾಗಿರುವ ಸನ್ನಿವೇಶಗಳಿವೆ:
- ಅತ್ಯಂತ ನಿರ್ದಿಷ್ಟ ಕಾಂಪೊನೆಂಟ್ ವರ್ತನೆ: ಒಂದು ಕಾಂಪೊನೆಂಟ್ ಹೆಚ್ಚು ವಿಶೇಷವಾದ, ಸ್ವಯಂ-ಒಳಗೊಂಡಿರುವ ಈವೆಂಟ್ ತರ್ಕವನ್ನು ಹೊಂದಿದ್ದರೆ, ಅದು ಅದರ ಪೂರ್ವಜರ ಡೆಲಿಗೇಟೆಡ್ ಹ್ಯಾಂಡ್ಲರ್ಗಳೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸುವ ಅಗತ್ಯವಿಲ್ಲದಿದ್ದಾಗ.
- `onChange` ನೊಂದಿಗೆ ಇನ್ಪುಟ್ ಎಲಿಮೆಂಟ್ಗಳು: ಟೆಕ್ಸ್ಟ್ ಇನ್ಪುಟ್ಗಳಂತಹ ನಿಯಂತ್ರಿತ ಕಾಂಪೊನೆಂಟ್ಗಳಿಗೆ, `onChange` ಲಿಸನರ್ಗಳನ್ನು ತಕ್ಷಣದ ಸ್ಟೇಟ್ ಅಪ್ಡೇಟ್ಗಳಿಗಾಗಿ ಸಾಮಾನ್ಯವಾಗಿ ಇನ್ಪುಟ್ ಎಲಿಮೆಂಟ್ನ ಮೇಲೆ ನೇರವಾಗಿ ಇರಿಸಲಾಗುತ್ತದೆ. ಈ ಈವೆಂಟ್ಗಳು ಸಹ ಬಬಲ್ ಆದರೂ, ಅವುಗಳನ್ನು ನೇರವಾಗಿ ನಿಭಾಯಿಸುವುದು ಪ್ರಮಾಣಿತ ಅಭ್ಯಾಸವಾಗಿದೆ.
- ಕಾರ್ಯಕ್ಷಮತೆ-ನಿರ್ಣಾಯಕ, ಅಧಿಕ-ಆವರ್ತನ ಈವೆಂಟ್ಗಳು: `mousemove` ಅಥವಾ `scroll` ನಂತಹ ಆಗಾಗ್ಗೆ ಫೈರ್ ಆಗುವ ಈವೆಂಟ್ಗಳಿಗೆ, ದೂರದ ಪೂರ್ವಜರಿಗೆ ಡೆಲಿಗೇಟ್ ಮಾಡುವುದು `event.target` ಅನ್ನು ಪುನರಾವರ್ತಿತವಾಗಿ ಪರಿಶೀಲಿಸುವ ಸ್ವಲ್ಪ ಓವರ್ಹೆಡ್ ಅನ್ನು ಪರಿಚಯಿಸಬಹುದು. ಆದಾಗ್ಯೂ, ಹೆಚ್ಚಿನ UI ಸಂವಹನಗಳಿಗೆ (ಕ್ಲಿಕ್ಗಳು, ಕೀಡೌನ್ಗಳು), ಡೆಲಿಗೇಷನ್ನ ಪ್ರಯೋಜನಗಳು ಈ ಕನಿಷ್ಠ ವೆಚ್ಚವನ್ನು ಮೀರಿಸುತ್ತವೆ.
ಸುಧಾರಿತ ಮಾದರಿಗಳು ಮತ್ತು ಪರಿಗಣನೆಗಳು
ಹೆಚ್ಚು ಸಂಕೀರ್ಣ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗಾಗಿ, ವಿಶೇಷವಾಗಿ ವೈವಿಧ್ಯಮಯ ಜಾಗತಿಕ ಬಳಕೆದಾರರನ್ನು ಪೂರೈಸುವಂತಹವುಗಳಿಗಾಗಿ, ಪೋರ್ಟಲ್ಗಳೊಳಗೆ ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್ ಅನ್ನು ನಿರ್ವಹಿಸಲು ನೀವು ಸುಧಾರಿತ ಮಾದರಿಗಳನ್ನು ಪರಿಗಣಿಸಬಹುದು.
ಕಸ್ಟಮ್ ಈವೆಂಟ್ ಡಿಸ್ಪ್ಯಾಚಿಂಗ್
ರಿಯಾಕ್ಟ್ನ ಸಿಂಥೆಟಿಕ್ ಈವೆಂಟ್ ಸಿಸ್ಟಮ್ ನಿಮ್ಮ ಅಗತ್ಯಗಳಿಗೆ ಸಂಪೂರ್ಣವಾಗಿ ಹೊಂದಿಕೆಯಾಗದ ಅತ್ಯಂತ ನಿರ್ದಿಷ್ಟ ಎಡ್ಜ್ ಕೇಸ್ಗಳಲ್ಲಿ (ಇದು ಅಪರೂಪ), ನೀವು ಹಸ್ತಚಾಲಿತವಾಗಿ ಕಸ್ಟಮ್ ಈವೆಂಟ್ಗಳನ್ನು ರವಾನಿಸಬಹುದು. ಇದು `CustomEvent` ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ರಚಿಸುವುದು ಮತ್ತು ಅದನ್ನು ಟಾರ್ಗೆಟ್ ಎಲಿಮೆಂಟ್ನಿಂದ ರವಾನಿಸುವುದನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ. ಆದಾಗ್ಯೂ, ಇದು ಸಾಮಾನ್ಯವಾಗಿ ರಿಯಾಕ್ಟ್ನ ಆಪ್ಟಿಮೈಸ್ಡ್ ಈವೆಂಟ್ ಸಿಸ್ಟಮ್ ಅನ್ನು ಬೈಪಾಸ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ಇದನ್ನು ಎಚ್ಚರಿಕೆಯಿಂದ ಮತ್ತು ಕಟ್ಟುನಿಟ್ಟಾಗಿ ಅಗತ್ಯವಿದ್ದಾಗ ಮಾತ್ರ ಬಳಸಬೇಕು, ಏಕೆಂದರೆ ಇದು ನಿರ್ವಹಣೆಯ ಸಂಕೀರ್ಣತೆಯನ್ನು ಪರಿಚಯಿಸಬಹುದು.
// ಪೋರ್ಟಲ್ ಕಾಂಪೊನೆಂಟ್ ಒಳಗೆ
const handleCustomAction = () => {
const event = new CustomEvent('my-custom-portal-event', { detail: { data: 'some info' }, bubbles: true });
document.dispatchEvent(event);
};
// ನಿಮ್ಮ ಮುಖ್ಯ ಆಪ್ನಲ್ಲಿ ಎಲ್ಲೋ ಒಂದು ಕಡೆ, ಉದಾ., ಎಫೆಕ್ಟ್ ಹುಕ್ನಲ್ಲಿ
useEffect(() => {
const handler = (event: Event) => {
if (event instanceof CustomEvent) {
console.log('ಕಸ್ಟಮ್ ಈವೆಂಟ್ ಸ್ವೀಕರಿಸಲಾಗಿದೆ:', event.detail);
}
};
document.addEventListener('my-custom-portal-event', handler);
return () => document.removeEventListener('my-custom-portal-event', handler);
}, []);
ಈ ವಿಧಾನವು ಸೂಕ್ಷ್ಮ ನಿಯಂತ್ರಣವನ್ನು ನೀಡುತ್ತದೆ ಆದರೆ ಈವೆಂಟ್ ಪ್ರಕಾರಗಳು ಮತ್ತು ಪೇಲೋಡ್ಗಳ ಎಚ್ಚರಿಕೆಯ ನಿರ್ವಹಣೆಯ ಅಗತ್ಯವಿರುತ್ತದೆ.
ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲರ್ಗಳಿಗಾಗಿ ಕಾಂಟೆಕ್ಸ್ಟ್ API
ಆಳವಾಗಿ ನೆಸ್ಟೆಡ್ ಪೋರ್ಟಲ್ ಕಂಟೆಂಟ್ ಹೊಂದಿರುವ ದೊಡ್ಡ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ, ಪ್ರಾಪ್ಸ್ ಮೂಲಕ `onClose` ಅಥವಾ ಇತರ ಹ್ಯಾಂಡ್ಲರ್ಗಳನ್ನು ರವಾನಿಸುವುದು ಪ್ರಾಪ್ ಡ್ರಿಲ್ಲಿಂಗ್ಗೆ ಕಾರಣವಾಗಬಹುದು. ರಿಯಾಕ್ಟ್ನ ಕಾಂಟೆಕ್ಸ್ಟ್ API ಒಂದು ಸೊಗಸಾದ ಪರಿಹಾರವನ್ನು ಒದಗಿಸುತ್ತದೆ:
// context/ModalContext.js
import React, { createContext, useContext } from 'react';
interface ModalContextType {
onClose?: () => void;
// ಅಗತ್ಯವಿರುವಂತೆ ಇತರ ಮೋಡಲ್-ಸಂಬಂಧಿತ ಹ್ಯಾಂಡ್ಲರ್ಗಳನ್ನು ಸೇರಿಸಿ
}
const ModalContext = createContext<ModalContextType>({});
export const useModal = () => useContext(ModalContext);
export const ModalProvider = ({ children, onClose }: ModalContextType & React.PropsWithChildren) => (
<ModalContext.Provider value={{ onClose }}>
{children}
</ModalContext.Provider>
);
// components/Modal.js (ಕಾಂಟೆಕ್ಸ್ಟ್ ಬಳಸಲು ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗಿದೆ)
// ... (ಇಂಪೋರ್ಟ್ಗಳು ಮತ್ತು modalRoot ಅನ್ನು ವ್ಯಾಖ್ಯಾನಿಸಲಾಗಿದೆ)
const Modal = ({ isOpen, onClose, children }: ModalProps) => {
const modalContentRef = useRef<HTMLDivElement>(null);
// ... (Escape ಕೀಗಾಗಿ useEffect, handleBackdropClick ಹೆಚ್ಚಾಗಿ ಒಂದೇ ಆಗಿರುತ್ತದೆ)
if (!isOpen) return null;
return ReactDOM.createPortal(
<div className="modal-overlay" onClick={handleBackdropClick}>
<div className="modal-content" ref={modalContentRef}>
<ModalProvider onClose={onClose}>{children}</ModalProvider> <!-- ಕಾಂಟೆಕ್ಸ್ಟ್ ಒದಗಿಸಿ -->
<button onClick={onClose} aria-label="Close modal">X</button>
</div>
</div>,
modalRoot
);
};
export default Modal;
// components/DeeplyNestedComponent.js (ಮೋಡಲ್ ಚಿಲ್ಡ್ರನ್ ಒಳಗೆ ಎಲ್ಲೋ)
import React from 'react';
import { useModal } from '../context/ModalContext';
const DeeplyNestedComponent = () => {
const { onClose } = useModal();
return (
<div>
<p>ಈ ಕಾಂಪೊನೆಂಟ್ ಮೋಡಲ್ನ ಆಳದಲ್ಲಿದೆ.</p>
{onClose && <button onClick={onClose}>ಆಳವಾದ ನೆಸ್ಟ್ನಿಂದ ಮುಚ್ಚಿ</button>}
</div>
);
};
ಕಾಂಟೆಕ್ಸ್ಟ್ API ಅನ್ನು ಬಳಸುವುದು ಹ್ಯಾಂಡ್ಲರ್ಗಳನ್ನು (ಅಥವಾ ಯಾವುದೇ ಇತರ ಸಂಬಂಧಿತ ಡೇಟಾ) ಕಾಂಪೊನೆಂಟ್ ಟ್ರೀಯ ಕೆಳಗೆ ಪೋರ್ಟಲ್ ಕಂಟೆಂಟ್ಗೆ ರವಾನಿಸಲು ಒಂದು ಸ್ವಚ್ಛ ಮಾರ್ಗವನ್ನು ಒದಗಿಸುತ್ತದೆ, ಕಾಂಪೊನೆಂಟ್ ಇಂಟರ್ಫೇಸ್ಗಳನ್ನು ಸರಳಗೊಳಿಸುತ್ತದೆ ಮತ್ತು ನಿರ್ವಹಣೆಯನ್ನು ಸುಧಾರಿಸುತ್ತದೆ, ವಿಶೇಷವಾಗಿ ಸಂಕೀರ್ಣ UI ವ್ಯವಸ್ಥೆಗಳಲ್ಲಿ ಸಹಯೋಗಿಸುವ ಅಂತರರಾಷ್ಟ್ರೀಯ ತಂಡಗಳಿಗೆ.
ಕಾರ್ಯಕ್ಷಮತೆಯ ಪರಿಣಾಮಗಳು
ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಸ್ವತಃ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಹೆಚ್ಚಿಸುತ್ತದೆ, ಆದರೆ ನಿಮ್ಮ `handleBackdropClick` ಅಥವಾ ಡೆಲಿಗೇಟೆಡ್ ತರ್ಕದ ಸಂಕೀರ್ಣತೆಯ ಬಗ್ಗೆ ಗಮನವಿರಲಿ. ನೀವು ಪ್ರತಿ ಕ್ಲಿಕ್ನಲ್ಲಿ ದುಬಾರಿ DOM ಟ್ರಾವರ್ಸಲ್ಗಳು ಅಥವಾ ಲೆಕ್ಕಾಚಾರಗಳನ್ನು ಮಾಡುತ್ತಿದ್ದರೆ, ಅದು ಕಾರ್ಯಕ್ಷಮತೆಯ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರಬಹುದು. ನಿಮ್ಮ ಪರಿಶೀಲನೆಗಳನ್ನು (ಉದಾ., `event.target.closest()`, `element.contains()`) ಸಾಧ್ಯವಾದಷ್ಟು ಸಮರ್ಥವಾಗಿರುವಂತೆ ಆಪ್ಟಿಮೈಜ್ ಮಾಡಿ. ಅತ್ಯಂತ ಅಧಿಕ-ಆವರ್ತನ ಈವೆಂಟ್ಗಳಿಗೆ, ಅಗತ್ಯವಿದ್ದರೆ ಡಿಬೌನ್ಸಿಂಗ್ ಅಥವಾ ಥ್ರಾಟ್ಲಿಂಗ್ ಅನ್ನು ಪರಿಗಣಿಸಿ, ಆದರೂ ಇದು ಮೋಡಲ್ಗಳಲ್ಲಿನ ಸರಳ ಕ್ಲಿಕ್/ಕೀಡೌನ್ ಈವೆಂಟ್ಗಳಿಗೆ ಕಡಿಮೆ ಸಾಮಾನ್ಯವಾಗಿದೆ.
ಜಾಗತಿಕ ಪ್ರೇಕ್ಷಕರಿಗೆ ಪ್ರವೇಶಸಾಧ್ಯತೆ (A11y) ಪರಿಗಣನೆಗಳು
ಪ್ರವೇಶಸಾಧ್ಯತೆ ಒಂದು ನಂತರದ ಆಲೋಚನೆಯಲ್ಲ; ಇದು ಒಂದು ಮೂಲಭೂತ ಅವಶ್ಯಕತೆಯಾಗಿದೆ, ವಿಶೇಷವಾಗಿ ವೈವಿಧ್ಯಮಯ ಅಗತ್ಯಗಳು ಮತ್ತು ಸಹಾಯಕ ತಂತ್ರಜ್ಞಾನಗಳನ್ನು ಹೊಂದಿರುವ ಜಾಗತಿಕ ಪ್ರೇಕ್ಷಕರಿಗಾಗಿ ನಿರ್ಮಿಸುವಾಗ. ಮೋಡಲ್ಗಳು ಅಥವಾ ಅಂತಹುದೇ ಓವರ್ಲೇಗಳಿಗಾಗಿ ಪೋರ್ಟಲ್ಗಳನ್ನು ಬಳಸುವಾಗ, ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್ ಪ್ರವೇಶಸಾಧ್ಯತೆಯಲ್ಲಿ ನಿರ್ಣಾಯಕ ಪಾತ್ರ ವಹಿಸುತ್ತದೆ:
- ಫೋಕಸ್ ನಿರ್ವಹಣೆ: ಒಂದು ಮೋಡಲ್ ತೆರೆದಾಗ, ಫೋಕಸ್ ಅನ್ನು ಪ್ರೋಗ್ರಾಮ್ಯಾಟಿಕ್ ಆಗಿ ಮೋಡಲ್ನೊಳಗಿನ ಮೊದಲ ಸಂವಾದಾತ್ಮಕ ಎಲಿಮೆಂಟ್ಗೆ ಸರಿಸಬೇಕು. ಮೋಡಲ್ ಮುಚ್ಚಿದಾಗ, ಫೋಕಸ್ ಅದನ್ನು ತೆರೆಯಲು ಕಾರಣವಾದ ಎಲಿಮೆಂಟ್ಗೆ ಹಿಂತಿರುಗಬೇಕು. ಇದನ್ನು ಸಾಮಾನ್ಯವಾಗಿ `useEffect` ಮತ್ತು `useRef` ನೊಂದಿಗೆ ನಿಭಾಯಿಸಲಾಗುತ್ತದೆ.
- ಕೀಬೋರ್ಡ್ ಸಂವಹನ: `Escape` ಕೀಲಿಯನ್ನು ಮುಚ್ಚುವ ಕಾರ್ಯ (ಪ್ರದರ್ಶಿಸಿದಂತೆ) ಒಂದು ನಿರ್ಣಾಯಕ ಪ್ರವೇಶಸಾಧ್ಯತೆ ಮಾದರಿಯಾಗಿದೆ. ಮೋಡಲ್ನೊಳಗಿನ ಎಲ್ಲಾ ಸಂವಾದಾತ್ಮಕ ಎಲಿಮೆಂಟ್ಗಳು ಕೀಬೋರ್ಡ್-ನ್ಯಾವಿಗೇಬಲ್ (`Tab` ಕೀ) ಆಗಿರುವುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ.
- ARIA ಗುಣಲಕ್ಷಣಗಳು: ಸೂಕ್ತವಾದ ARIA ಪಾತ್ರಗಳು ಮತ್ತು ಗುಣಲಕ್ಷಣಗಳನ್ನು ಬಳಸಿ. ಮೋಡಲ್ಗಳಿಗೆ, `role="dialog"` ಅಥವಾ `role="alertdialog"`, `aria-modal="true"`, ಮತ್ತು `aria-labelledby` ಅಥವಾ `aria-describedby` ಅತ್ಯಗತ್ಯ. ಈ ಗುಣಲಕ್ಷಣಗಳು ಸ್ಕ್ರೀನ್ ರೀಡರ್ಗಳಿಗೆ ಮೋಡಲ್ನ ಉಪಸ್ಥಿತಿಯನ್ನು ಘೋಷಿಸಲು ಮತ್ತು ಅದರ ಉದ್ದೇಶವನ್ನು ವಿವರಿಸಲು ಸಹಾಯ ಮಾಡುತ್ತವೆ.
- ಫೋಕಸ್ ಟ್ರ್ಯಾಪಿಂಗ್: ಮೋಡಲ್ನೊಳಗೆ ಫೋಕಸ್ ಟ್ರ್ಯಾಪಿಂಗ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಿ. ಇದು ಬಳಕೆದಾರರು `Tab` ಒತ್ತಿದಾಗ, ಫೋಕಸ್ ಕೇವಲ ಮೋಡಲ್ನ *ಒಳಗಿನ* ಎಲಿಮೆಂಟ್ಗಳ ಮೂಲಕ ಚಲಿಸುತ್ತದೆ, ಹಿನ್ನೆಲೆ ಅಪ್ಲಿಕೇಶನ್ನಲ್ಲಿನ ಎಲಿಮೆಂಟ್ಗಳ ಮೂಲಕ ಅಲ್ಲ ಎಂದು ಖಚಿತಪಡಿಸುತ್ತದೆ. ಇದನ್ನು ಸಾಮಾನ್ಯವಾಗಿ ಮೋಡಲ್ನ ಮೇಲೆ ಹೆಚ್ಚುವರಿ `keydown` ಹ್ಯಾಂಡ್ಲರ್ಗಳೊಂದಿಗೆ ಸಾಧಿಸಲಾಗುತ್ತದೆ.
ದೃಢವಾದ ಪ್ರವೇಶಸಾಧ್ಯತೆ ಕೇವಲ ಅನುಸರಣೆಯ ಬಗ್ಗೆ ಅಲ್ಲ; ಇದು ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ನ ವ್ಯಾಪ್ತಿಯನ್ನು ಅಂಗವೈಕಲ್ಯ ಹೊಂದಿರುವ ವ್ಯಕ್ತಿಗಳನ್ನು ಒಳಗೊಂಡಂತೆ ವಿಶಾಲವಾದ ಜಾಗತಿಕ ಬಳಕೆದಾರರಿಗೆ ವಿಸ್ತರಿಸುತ್ತದೆ, ಪ್ರತಿಯೊಬ್ಬರೂ ನಿಮ್ಮ UI ನೊಂದಿಗೆ ಪರಿಣಾಮಕಾರಿಯಾಗಿ ಸಂವಹನ ನಡೆಸಬಹುದೆಂದು ಖಚಿತಪಡಿಸುತ್ತದೆ.
ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್ಗಾಗಿ ಉತ್ತಮ ಅಭ್ಯಾಸಗಳು
ಸಾರಾಂಶವಾಗಿ, ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ಗಳೊಂದಿಗೆ ಈವೆಂಟ್ಗಳನ್ನು ಪರಿಣಾಮಕಾರಿಯಾಗಿ ನಿಭಾಯಿಸಲು ಪ್ರಮುಖ ಉತ್ತಮ ಅಭ್ಯಾಸಗಳು ಇಲ್ಲಿವೆ:
- ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಅನ್ನು ಅಳವಡಿಸಿಕೊಳ್ಳಿ: ಯಾವಾಗಲೂ ಸಾಮಾನ್ಯ ಪೂರ್ವಜರಿಗೆ (ಮೋಡಲ್ನ ಬ್ಯಾಕ್ಡ್ರಾಪ್ನಂತಹ) ಒಂದೇ ಈವೆಂಟ್ ಲಿಸನರ್ ಅನ್ನು ಲಗತ್ತಿಸಲು ಆದ್ಯತೆ ನೀಡಿ ಮತ್ತು ಕ್ಲಿಕ್ ಮಾಡಿದ ಎಲಿಮೆಂಟ್ ಅನ್ನು ಗುರುತಿಸಲು `event.target` ಅನ್ನು `element.contains()` ಅಥವಾ `event.target.closest()` ನೊಂದಿಗೆ ಬಳಸಿ.
- ರಿಯಾಕ್ಟ್ನ ಸಿಂಥೆಟಿಕ್ ಈವೆಂಟ್ಗಳನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಿ: ರಿಯಾಕ್ಟ್ನ ಸಿಂಥೆಟಿಕ್ ಈವೆಂಟ್ ಸಿಸ್ಟಮ್ ಪೋರ್ಟಲ್ಗಳಿಂದ ಈವೆಂಟ್ಗಳನ್ನು ಅವುಗಳ ತಾರ್ಕಿಕ ರಿಯಾಕ್ಟ್ ಕಾಂಪೊನೆಂಟ್ ಟ್ರೀಯ ಮೂಲಕ ಬಬಲ್ ಆಗುವಂತೆ ಪರಿಣಾಮಕಾರಿಯಾಗಿ ಮರು-ಲಕ್ಷ್ಯಗೊಳಿಸುತ್ತದೆ, ಡೆಲಿಗೇಷನ್ ಅನ್ನು ವಿಶ್ವಾಸಾರ್ಹವಾಗಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ನೆನಪಿಡಿ.
- ಜಾಗತಿಕ ಲಿಸನರ್ಗಳನ್ನು ವಿವೇಚನೆಯಿಂದ ನಿರ್ವಹಿಸಿ: `Escape` ಕೀ ಒತ್ತಡಗಳಂತಹ ಜಾಗತಿಕ ಈವೆಂಟ್ಗಳಿಗೆ, `useEffect` ಹುಕ್ನೊಳಗೆ ನೇರವಾಗಿ `document` ಗೆ ಲಿಸನರ್ಗಳನ್ನು ಲಗತ್ತಿಸಿ, ಸರಿಯಾದ ಕ್ಲೀನಪ್ ಅನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ.
- `stopPropagation()` ಅನ್ನು ಕಡಿಮೆ ಮಾಡಿ: `event.stopPropagation()` ಅನ್ನು ಮಿತವಾಗಿ ಬಳಸಿ. ಇದು ಸಂಕೀರ್ಣ ಈವೆಂಟ್ ಹರಿವುಗಳನ್ನು ರಚಿಸಬಹುದು. ವಿಭಿನ್ನ ಕ್ಲಿಕ್ ಟಾರ್ಗೆಟ್ಗಳನ್ನು ಸಹಜವಾಗಿ ನಿಭಾಯಿಸಲು ನಿಮ್ಮ ಡೆಲಿಗೇಷನ್ ತರ್ಕವನ್ನು ವಿನ್ಯಾಸಗೊಳಿಸಿ.
- ಪ್ರವೇಶಸಾಧ್ಯತೆಗೆ ಆದ್ಯತೆ ನೀಡಿ: ಆರಂಭದಿಂದಲೇ ಸಮಗ್ರ ಪ್ರವೇಶಸಾಧ್ಯತೆ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಿ, ಫೋಕಸ್ ನಿರ್ವಹಣೆ, ಕೀಬೋರ್ಡ್ ನ್ಯಾವಿಗೇಷನ್, ಮತ್ತು ಸೂಕ್ತ ARIA ಗುಣಲಕ್ಷಣಗಳನ್ನು ಒಳಗೊಂಡಂತೆ.
- DOM ರೆಫರೆನ್ಸ್ಗಳಿಗಾಗಿ `useRef` ಅನ್ನು ಬಳಸಿಕೊಳ್ಳಿ: ನಿಮ್ಮ ಪೋರ್ಟಲ್ನೊಳಗಿನ DOM ಎಲಿಮೆಂಟ್ಗಳಿಗೆ ನೇರ ರೆಫರೆನ್ಸ್ಗಳನ್ನು ಪಡೆಯಲು `useRef` ಅನ್ನು ಬಳಸಿ, ಇದು `element.contains()` ಪರಿಶೀಲನೆಗಳಿಗೆ ನಿರ್ಣಾಯಕವಾಗಿದೆ.
- ಸಂಕೀರ್ಣ ಪ್ರಾಪ್ಸ್ಗಳಿಗಾಗಿ ಕಾಂಟೆಕ್ಸ್ಟ್ API ಅನ್ನು ಪರಿಗಣಿಸಿ: ಪೋರ್ಟಲ್ಗಳೊಳಗಿನ ಆಳವಾದ ಕಾಂಪೊನೆಂಟ್ ಟ್ರೀಗಳಿಗಾಗಿ, ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲರ್ಗಳು ಅಥವಾ ಇತರ ಹಂಚಿಕೆಯ ಸ್ಥಿತಿಯನ್ನು ರವಾನಿಸಲು ಕಾಂಟೆಕ್ಸ್ಟ್ API ಅನ್ನು ಬಳಸಿ, ಪ್ರಾಪ್ ಡ್ರಿಲ್ಲಿಂಗ್ ಅನ್ನು ಕಡಿಮೆ ಮಾಡಿ.
- ಸಂಪೂರ್ಣವಾಗಿ ಪರೀಕ್ಷಿಸಿ: ಪೋರ್ಟಲ್ಗಳ ಕ್ರಾಸ್-DOM ಸ್ವರೂಪವನ್ನು ಗಮನದಲ್ಲಿಟ್ಟುಕೊಂಡು, ವಿವಿಧ ಬಳಕೆದಾರರ ಸಂವಹನಗಳು, ಬ್ರೌಸರ್ ಪರಿಸರಗಳು, ಮತ್ತು ಸಹಾಯಕ ತಂತ್ರಜ್ಞಾನಗಳಾದ್ಯಂತ ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್ ಅನ್ನು ಕಠಿಣವಾಗಿ ಪರೀಕ್ಷಿಸಿ.
ತೀರ್ಮಾನ
ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ಗಳು ಸುಧಾರಿತ, ದೃಷ್ಟಿಗೆ ಆಕರ್ಷಕವಾದ ಬಳಕೆದಾರ ಇಂಟರ್ಫೇಸ್ಗಳನ್ನು ನಿರ್ಮಿಸಲು ಅನಿವಾರ್ಯ ಸಾಧನವಾಗಿದೆ. ಆದಾಗ್ಯೂ, ಪೋಷಕ ಕಾಂಪೊನೆಂಟ್ನ DOM ಶ್ರೇಣಿಯ ಹೊರಗೆ ಕಂಟೆಂಟ್ ಅನ್ನು ರೆಂಡರ್ ಮಾಡುವ ಅವುಗಳ ಸಾಮರ್ಥ್ಯವು ಈವೆಂಟ್ ಹ್ಯಾಂಡ್ಲಿಂಗ್ಗಾಗಿ ವಿಶಿಷ್ಟ ಪರಿಗಣನೆಗಳನ್ನು ಪರಿಚಯಿಸುತ್ತದೆ. ರಿಯಾಕ್ಟ್ನ ಸಿಂಥೆಟಿಕ್ ಈವೆಂಟ್ ಸಿಸ್ಟಮ್ ಅನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವ ಮೂಲಕ ಮತ್ತು ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಕಲೆಯಲ್ಲಿ ಪರಿಣತಿ ಹೊಂದುವ ಮೂಲಕ, ಡೆವಲಪರ್ಗಳು ಈ ಸವಾಲುಗಳನ್ನು ನಿವಾರಿಸಬಹುದು ಮತ್ತು ಹೆಚ್ಚು ಸಂವಾದಾತ್ಮಕ, ಕಾರ್ಯಕ್ಷಮತೆ ಮತ್ತು ಪ್ರವೇಶಸಾಧ್ಯ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನಿರ್ಮಿಸಬಹುದು.
ಈವೆಂಟ್ ಡೆಲಿಗೇಷನ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದು ನಿಮ್ಮ ಜಾಗತಿಕ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಆಧಾರವಾಗಿರುವ DOM ರಚನೆಯನ್ನು ಲೆಕ್ಕಿಸದೆ, ಸ್ಥಿರ ಮತ್ತು ದೃಢವಾದ ಬಳಕೆದಾರ ಅನುಭವವನ್ನು ಒದಗಿಸುತ್ತವೆ ಎಂದು ಖಚಿತಪಡಿಸುತ್ತದೆ. ಇದು ಸ್ವಚ್ಛ, ಹೆಚ್ಚು ನಿರ್ವಹಿಸಬಲ್ಲ ಕೋಡ್ಗೆ ಕಾರಣವಾಗುತ್ತದೆ ಮತ್ತು ಸ್ಕೇಲೆಬಲ್ UI ಡೆವಲಪ್ಮೆಂಟ್ಗೆ ದಾರಿ ಮಾಡಿಕೊಡುತ್ತದೆ. ಈ ಮಾದರಿಗಳನ್ನು ಅಳವಡಿಸಿಕೊಳ್ಳಿ, ಮತ್ತು ನಿಮ್ಮ ಮುಂದಿನ ಪ್ರಾಜೆಕ್ಟ್ನಲ್ಲಿ ರಿಯಾಕ್ಟ್ ಪೋರ್ಟಲ್ಗಳ ಸಂಪೂರ್ಣ ಶಕ್ತಿಯನ್ನು ಬಳಸಿಕೊಳ್ಳಲು ನೀವು ಸಜ್ಜಾಗುತ್ತೀರಿ, ವಿಶ್ವಾದ್ಯಂತ ಬಳಕೆದಾರರಿಗೆ ಅಸಾಧಾರಣ ಡಿಜಿಟಲ್ ಅನುಭವಗಳನ್ನು ನೀಡುತ್ತೀರಿ.