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
相关产品推荐
相关产品推荐

