I am trying to pass context to an element manually rendered to the dom (because of a third-party library).
For some reason the context is not being passed correctly. I end up with:
Portal Context: false
Regular Context: true
import React, { useEffect, useContext, useRef } from "react";
import ReactDOM from "react-dom";
const AppContext = React.createContext(false);
function RenderAppContext() {
const context = useContext(AppContext);
return <>{JSON.stringify(context)}</>;
}
function App() {
const portalRef = useRef(null);
useEffect(() => {
ReactDOM.render(
ReactDOM.createPortal(<RenderAppContext />, portalRef.current),
document.createElement("div")
);
}, []);
return (
<AppContext.Provider value={true}>
<div style={{ display: "flex" }}>
<span>Portal Context:</span>
<div ref={portalRef} />
</div>
<div style={{ display: "flex" }}>
<span>Regular Context:</span>
<RenderAppContext />
</div>
</AppContext.Provider>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
https://codesandbox.io/s/dawn-surf-wt0if4?file=/src/index.js
ReactDOM.render
is creating another react app, with completely separate contexts. JustReactDOM.createPortal(<RenderAppContext />, portalRef.current)
should be all that is needed for your portal. If you want to move where it is rendered to outside of the structure of your app just replaceportalRef.current
with the DOM element where you would like it to render (i.e. add an extra div to your body tag in your HTML give it an id of "portal" and then usedocument.getElementById('portal')
or your preferred method of getting a reference to the element) - Jacob Smit