I am working with react cytoscape library. Try to integrate to popper plugin of cytoscape. the popper "content" property expect to return a div element describe the popper which appended to the "body" element. Since the context provider is under the root element , that div can't be consumer of that context. How can I use the same context also in the popper element which define outside the root.
Working with react component for cytoscape but the plugins of cytoscape are in pure js.
<body>
<div id=root>
<Style_Provider>
.
.
.
</Style_Provider>
</div>
<div id="popper">
// need to access to style context
</div>
</body>
As Eric Hasselbring said, portals address this use case:
Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.
Here's an example, using context:
const ExampleContext = React.createContext(
"default context"
);
class Example extends React.Component {
render() {
return (
<ExampleContext.Provider value="context from Example">
<div>
This is the parent comnponent.
<MyPortal />
</div>
</ExampleContext.Provider>
);
}
}
class MyPortal extends React.Component {
static contextType = ExampleContext;
render() {
return ReactDOM.createPortal(
<div>This is "my portal," context stuff is "{this.context}"</div>,
document.getElementById("portal")
);
}
}
ReactDOM.render(
<Example />,
document.getElementById("root")
);
<div id="root"></div>
<hr>
<div id="portal"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
In a comment you said:
the popper creates those 'divs' dynamically. Hence, I cant create 'MyPortal' component initially.
Just make the creation of the portal conditional. Here's the above, but with a button to show/hide the portal:
const ExampleContext = React.createContext(
"default context"
);
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
showPortal: false
};
this.showHideClick = this.showHideClick.bind(this);
}
showHideClick() {
this.setState(({showPortal}) => ({showPortal: !showPortal}));
}
render() {
const {showPortal} = this.state;
return (
<ExampleContext.Provider value="context from Example">
<div>
This is the parent comnponent.
<input type="button" value={showPortal ? "Hide" : "Show"} onClick={this.showHideClick}/>
{showPortal && <MyPortal />}
</div>
</ExampleContext.Provider>
);
}
}
class MyPortal extends React.Component {
static contextType = ExampleContext;
render() {
return ReactDOM.createPortal(
<div>This is "my portal," context stuff is "{this.context}"</div>,
document.getElementById("portal")
);
}
}
ReactDOM.render(
<Example />,
document.getElementById("root")
);
<div id="root"></div>
<hr>
<div id="portal"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With