1

我创建了一个门户组件,它在新窗口中打开一个子组件。我可以访问子组件内部的 Redux 状态,但是当 Redux 状态发生变化时,子组件不会重新渲染,并且似乎丢失了对我调用门户组件的父节点的引用。

弹出窗口.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);
        }
    });
}

父组件.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>
  )
}

父组件按预期重新渲染,但子组件丢失引用并且不重新渲染。

4

0 回答 0