You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React新浏览器标签页使用createPortal时styled-components样式不加载

问题原因

styled-components 默认会将自动生成的CSS样式注入到当前父页面的<head>节点中,通过window.open创建的是独立的浏览器上下文,新标签页的文档和原页面完全隔离,新页面的<head>中不存在styled-components生成的样式规则,因此挂载到新页面的元素无法匹配到对应样式。
问题现象如下:
样式未生效展示图

修复方案

修改NewBrowserTab组件,在新窗口初始化完成后,将原页面的样式同步到新窗口中,修改后的代码如下:

import { useState, useRef, useEffect } from 'react'
import { createPortal } from 'react-dom'

export const NewBrowserTab = ({ children }) => {
  const [container, setContainer] = useState(null)
  const newWindow = useRef(null)

  useEffect(() => {
    setContainer(document.createElement('div'))
  }, [])

  useEffect(() => {
    if (container) {
      newWindow.current = window.open('', '')
      // 初始化新窗口完整文档结构
      newWindow.current.document.open()
      newWindow.current.document.write('<!DOCTYPE html><html><head></head><body></body></html>')
      newWindow.current.document.close()

      // 同步原页面所有样式到新窗口
      const copyStyles = () => {
        const newWindowHead = newWindow.current.document.head
        // 复制所有样式节点,包括styled-components生成的样式
        document.querySelectorAll('style, link[rel="stylesheet"]').forEach(node => {
          newWindowHead.appendChild(node.cloneNode(true))
        })
      }
      copyStyles()

      newWindow.current.document.body.appendChild(container)

      return () => {
        newWindow.current.close()
      }
    }
  }, [container])

  return container && createPortal(children, container)
}

如果项目存在动态更新的样式,可以额外添加MutationObserver监听原页面的style节点变化,触发时自动同步新的样式到新窗口即可。

内容的提问来源于stack exchange,提问作者OutlawSloth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 02:00:02