Sometimes, we want to open a component in new window on a click in React.
In this article, we’ll look at how to open a component in new window on a click in React.
Open a Component in New Window on a Click in React
To open a component in new window on a click in React, we can call window.open
with the element we created.
For instance, we write:
import React, { useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
const RenderInWindow = (props) => {
const [container, setContainer] = useState(null);
const newWindow = useRef(window);
useEffect(() => {
const div = document.createElement("div");
setContainer(div);
}, []);
useEffect(() => {
if (container) {
newWindow.current = window.open(
"",
"",
"width=600,height=400,left=200,top=200"
);
newWindow.current.document.body.appendChild(container);
const curWindow = newWindow.current;
return () => curWindow.close();
}
}, [container]);
return container && createPortal(props.children, container);
};
export default function App() {
const [open, setOpen] = useState();
return (
<>
<button onClick={() => setOpen(true)}>open</button>
{open && <RenderInWindow>hello world</RenderInWindow>}
</>
);
}
to create the RenderInWindow
component that opens a new window when it mounts.
To do this, we create the container
state with useState
.
And we create a ref to store the window
object.
In the first useEffect
callback, we create a div that we use as the content of the element when RenderInWindow
mounts and call setContainer
to set the div
as the value of `container.
In the 2nd useEffect
callback, we check if container
is set.
If it is, then we call window.open
and set the returned window object as the value of newWindow.current
.
And we set the content of the window with:
newWindow.current.document.body.appendChild(container);
And then we get newWindow.current
and set it to curWindow
.
Finally we return a function that calls curWindow.close
to close the window when the component unmounts.
Then we return a portal with the window.
We get the content of the window from the children
prop.
In App
, we render the RenderInWindow
component with the content of the popup window when open
is true
.
And we make open
true
when we click on open.
Therefore, we should see ‘hello world’ displayed in a popup window when we click on open.
Conclusion
To open a component in new window on a click in React, we can call window.open
with the element we created.
9 replies on “How to Open a Component in New Window on a Click in React?”
Tying to use your code with typescript. but I get error on the line:
newWindow.current = window.open(
Error:
[{
“resource”: “/C:/Users/ogal/source/repos/SPFx/SPFx14/Ace2InboxStatus/src/webparts/ace2InboxStatus/components/Child/OneJobWindow.tsx”,
“owner”: “typescript”,
“code”: “2322”,
“severity”: 8,
“message”: “Type ‘Window’ is not assignable to type ‘Window & typeof globalThis’.\n Type ‘Window’ is missing the following properties from type ‘typeof globalThis’: globalThis, eval, parseInt, parseFloat, and 611 more.”,
“source”: “ts”,
“startLineNumber”: 18,
“startColumn”: 13,
“endLineNumber”: 18,
“endColumn”: 30
}]
do you have a typing for it?
Did you include ‘dom’ in compilerOptions.lib in tsconfig.json?
Hi I am using the above code to open a component in new window , for the first time the window is opening. For the second time window is not opening and I didn’t see any errors in my code. May I know why its happening.
Did you close the window before trying to open it again?
The problem is that he never set the open state in false. It is necessary to set the open state false to be able to open the window again. I am still trying to achieve this
I was able to fix this issue with this code, sorry for the typescript anys, all testing
const RenderInWindow = (props:any) => {
const [container, setContainer] = useState();
const newWindow = useRef(window);
useEffect(() => {
const div = document.createElement(“div”);
setContainer(div);
}, []);
useEffect(() => {
if (container) {
newWindow.current = window.open(
“”,
“”,
“width=600,height=400,left=200,top=200”
);
newWindow.current.addEventListener("beforeunload", () => {
props.setOpenFunc(false)
})
newWindow.current.document.body.appendChild(container);
const curWindow = newWindow.current;
return () => curWindow.close();
}
}, [container]);
return container ? createPortal(props.children, container) :
;
};
setOpen(t)}>
hello world
setInput(e.target.value) } />
setOpen(!open)}>Close
Hi I would like to know if I want to launch a class component, how do i do it?
class component instead of div*
Hey great job with this code it really helped me out a lot. I do have one question as to why my styled-components aren’t visible when the content is loaded in the new window. Could anyone offer assistance here?