How to re-render React component in a portal when the Redux state updates?

Viewed 232

I created a portal component which opens a child component in the new window. I can access the Redux state inside the child component, but when the Redux state changes, the child is not re-rendering and seems to lose the reference to the parent node from which I called the portal component.

PopupWindow.jsx

    export const PopupWindow = (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(
                "", "My window", `width=${props.width},height=${props.height},left=200,top=200,resizable=0`
            );
            newWindow.current.document.title = props.name
            newWindow.current.document.body.style.overflowY = props.overflowY
            newWindow.current.document.body.appendChild(container);
            copyStyles(document, newWindow.current.document)
            const curWindow = newWindow.current;
            return () => curWindow.close();
        }
    }, [container]);

    window.addEventListener("beforeunload", (ev) => {
        ev.preventDefault();
        return props.onClose
    });

    return container && createPortal(props.children, container)
}

function copyStyles(sourceDoc, targetDoc) {
    Array.from(sourceDoc.styleSheets).forEach(styleSheet => {
        if (styleSheet.cssRules) { // true for inline styles
            const newStyleEl = sourceDoc.createElement('style');

            Array.from(styleSheet.cssRules).forEach(cssRule => {
                newStyleEl.appendChild(sourceDoc.createTextNode(cssRule.cssText));
            });

            targetDoc.head.appendChild(newStyleEl);
        } else if (styleSheet.href) { // true for stylesheets loaded from a URL
            const newLinkEl = sourceDoc.createElement('link');

            newLinkEl.rel = 'stylesheet';
            newLinkEl.href = styleSheet.href;
            targetDoc.head.appendChild(newLinkEl);
        }
    });
}

ParentCompoent.jsx

const ParentCompoent = () =>{
  const [isChildOpen,setIsChildOpen] = useState(false)
  return(
    {isChildOpen && <PortalComponent><ChildComponent/></PortalComponent>}
  )
}

ChildComponent.jsx

const ChildComponent = () =>{
  const reduxtState = useSelector(state=>state)

  useEffect(()=>{
    console.log(reduxState)
  }, [reduxState])

  return(
    <div>{reduxState}</div>
  )
}

The parent component is re-rendering as expected but the child component looses the reference and does not re-render.

0 Answers
Related