← Back to React Course | Chapter 13: Advanced React & Architecture | Lesson 2 of 14

React Portals की जानकारी

एक React Portal एक secret tunnel जैसा है जो एक component को house के totally different room में appear होने देता है, भले ही यह officially अपने original room से control हो रहा हो।
Syntax
markup
import { createPortal } from "react-dom";

function Component() {
  return createPortal(
    <div>Content</div>,
    document.getElementById("target-id")
  );
}

Portals क्यों मौजूद हैं: Overflow/Z-Index Problem

एक modal जो एक component के अंदर deeply nested है 'overflow: hidden' या एक specific stacking context के साथ visually clipped या दूसरे elements के पीछे hidden हो सकता है, भले ही आप इसका z-index कितना भी high set करें।

Portals इसे solve करते हैं modal के actual DOM elements को page में कहीं और render करके, उस parent की CSS constraints को completely escape करते हुए।

Note: एक common setup है एक dedicated '#modal-root' <div> directly <body> के नीचे placed, आपके main app की DOM structure से completely बाहर।
Warning: बिना एक portal के, एक deeply-nested modal invisibly clipped हो सकता है एक ancestor के overflow या stacking rules से, भले ही code correct लगे।

उदाहरण: Why Portals Exist: The Overflow/Z-Index Problem

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
function Modal({ children }) {
  return ReactDOM.createPortal(
    <div style={{ position: "fixed", top: 20, left: 20, background: "white", border: "1px solid #333", padding: "16px" }}>
      {children}
    </div>,
    document.body
  );
}
function App() {
  return <div><p>Main app content</p><Modal><p>I'm rendered via a portal, into document.body</p></Modal></div>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

Portals Events के लिए अब भी React Tree Follow करते हैं

भले ही एक portal के actual DOM elements page में कहीं और रहते हैं, React अब भी उन्हें props, context, और event bubbling के लिए original component tree का हिस्सा मानता है।

एक portal के content के अंदर एक click अब भी इसके REACT ancestors के through bubble करेगी, इसके DOM ancestors के through नहीं।

Note: इसका मतलब है एक parent से Context values अब भी correctly एक portal के content में flow करती हैं, exactly जैसे इसे portal न किया गया हो।
Warning: यह मान न लें कि एक portal के बाहर click करने का मतलब (DOM sense में) इसके React event system में इसके बाहर click करना है — event bubbling React के tree को follow करती है, जो आपको surprise कर सकता है।

उदाहरण: Portals Still Follow the React Tree for Events

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
const ThemeContext = React.createContext("light");
function Modal({ children }) {
  return ReactDOM.createPortal(<div style={{border: "1px solid #333", padding: "8px"}}>{children}</div>, document.body);
}
function ModalContent() {
  const theme = React.useContext(ThemeContext);
  return <p>Theme inside portal: {theme}</p>;
}
function App() {
  return <ThemeContext.Provider value="dark"><Modal><ModalContent /></Modal></ThemeContext.Provider>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

Target Node को पहले से मौजूद होना चाहिए

createPortal का second argument एक real, already-existing DOM node होना चाहिए — React इसे आपके लिए नहीं बनाता। यह target usually आपके HTML में पहले से मौजूद एक plain <div> है (जैसे index.html), React के अपने root element से separate।

Note: document.body खुद एक valid, always-existing target है अगर आप एक separate dedicated div नहीं add करना चाहते।
Warning: एक DOM node pass करना जो अभी मौजूद नहीं है (जैसे एक जो render नहीं हुआ, या एक typo'd ID) createPortal इसे उपयोग करने की कोशिश करते ही एक error throw करता है।

उदाहरण: The Target Node Must Already Exist

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
function TooltipPortal({ children }) {
  return ReactDOM.createPortal(
    <div style={{ position: "fixed", bottom: 20, right: 20, background: "black", color: "white", padding: "8px" }}>
      {children}
    </div>,
    document.body // always exists, safe target
  );
}
function App() {
  return <TooltipPortal><span>I'm a portaled tooltip</span></TooltipPortal>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. यह भूल जाना कि createPortal को pass किया गया target DOM node actually HTML में मौजूद होना चाहिए इससे पहले कि portal इसमें render करने की कोशिश करे।
  2. यह मान लेना कि एक portal events के लिए भी React के component tree को तोड़ता है — event bubbling अब भी React tree को follow करती है, DOM tree को नहीं।
  3. हर render पर एक brand-new target DOM node बनाना instead of एक stable वाला reuse करना।
चैप्टर सारांश
  • ReactDOM.createPortal(children, domNode) children को actual DOM के एक अलग हिस्से में render करता है।
  • यह commonly modals, tooltips, और dropdowns के लिए उपयोग किया जाता है जिन्हें एक parent के overflow:hidden या z-index stacking context से escape करना हो।
  • DOM में कहीं और render होने के बावजूद, एक portal का content अब भी state, context, और event bubbling के लिए React component tree का एक normal हिस्सा जैसा behave करता है।
  • Target DOM node को पहले से मौजूद होना चाहिए (usually index.html में एक dedicated <div>) createPortal इसमें render करने से पहले।
ब्राउज़र सपोर्ट

React 16.0 से available (Portals introduced)।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.