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

SolidJS函数组件渲染异常:开发正常生产报错,求正确实现方式

问题分析与解决

你的代码确实误用了Solid的createRoot方法,这是导致生产环境报错的核心原因。

错误原因

Solid的createRoot回调函数必须接收一个dispose参数(用于销毁根节点、清理反应式依赖),而你的代码里的回调是无参数的()=>{ render(<Menu />, menu_e) }。开发环境下Solid的容错性较高,但生产环境打包优化后,内部逻辑会尝试调用该回调的返回值(render无返回值),从而抛出TypeError: z(...) is not a function的错误。

另外你混淆了React和Solid的createRoot用法:React是createRoot(element).render(<Component/>),但Solid的createRoot是用于创建独立反应式根的工具,写法完全不同。

正确写法

根据需求选择两种方案:

方案1:直接渲染(无需独立根)

如果菜单不需要独立的反应式根,直接调用render即可:

export function createMenu(e, Menu) {
    let x = e.clientX
    let y = e.clientY
    let menu_e = document.createElement('DIV')
    menu_e.className = "menu"
    menu_e.tabIndex = "-1"
    menu_e.style.top = `${y}px`
    menu_e.style.left = `${x}px`
    menu_e.id = "menu-option"

    document.body.appendChild(menu_e)

    // 直接渲染组件到目标元素
    render(<Menu />, menu_e)
}

方案2:创建独立反应式根(推荐,便于后续清理)

如果需要独立管理菜单的反应式依赖(比如关闭菜单时清理资源),正确使用createRoot:

export function createMenu(e, Menu) {
    let x = e.clientX
    let y = e.clientY
    let menu_e = document.createElement('DIV')
    menu_e.className = "menu"
    menu_e.tabIndex = "-1"
    menu_e.style.top = `${y}px`
    menu_e.style.left = `${x}px`
    menu_e.id = "menu-option"

    document.body.appendChild(menu_e)

    // 正确的createRoot用法:接收dispose参数
    const dispose = createRoot((dispose) => {
        render(<Menu />, menu_e)
        // 可保存dispose,后续关闭菜单时调用 dispose() 清理资源
        return dispose
    })

    // 示例:点击文档其他区域关闭菜单并清理
    const closeMenu = () => {
        document.body.removeChild(menu_e)
        dispose()
        document.removeEventListener('click', closeMenu)
    }
    document.addEventListener('click', closeMenu)
}

额外提示

  • 后续销毁菜单时,要同步移除DOM元素并调用dispose(如果用了独立根),避免内存泄漏。
  • 生产环境报错的混淆变量名(如z、b1)是打包工具压缩后的结果,核心问题还是createRoot的用法错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:22:47