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

SolidJS JSX渲染时SVG节点被移除的原因排查

问题分析与解决

问题现象

自定义下拉组件中,选中项的SVG图标初始正常渲染,但展开下拉框时图标被移除;选中新选项后图标重新显示,再次展开又消失。调试确认value().icon状态未发生变化,JSX中也未对SVG设置条件渲染逻辑。

根因

你直接将SVG DOM节点存入了状态中,而DOM节点在浏览器中只能存在于一个DOM位置。当展开下拉触发组件更新时,SolidJS的DOM更新机制会尝试处理这个节点,导致原节点被从当前位置移除(即使状态里的节点引用还在,但它已经不属于当前DOM树了)。

解决方案

不要存储DOM节点,改为存储SVG的可渲染描述信息,两种可行方式:

方式1:使用Solid组件封装SVG

将SVG封装成独立组件,状态中存储组件本身:

// 定义SVG组件
const IconHome = () => <svg viewBox="0 0 24 24"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>;

// 选项数据存储组件
const options = [
  { icon: IconHome, label: "首页" },
  // 其他选项
];

// 渲染时直接调用组件
<button onClick={() => setExpanded(prev => !prev)}>
  <span>{value().icon()}</span>
  <span>{value().label}</span>
  <svg />
</button>

方式2:存储SVG属性数据

如果是动态SVG,可存储viewBox、路径等核心数据,渲染时动态生成SVG:

// 选项数据存储SVG属性
const options = [
  { 
    icon: { viewBox: "0 0 24 24", path: "M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" }, 
    label: "首页" 
  },
  // 其他选项
];

// 渲染时动态生成SVG
<button onClick={() => setExpanded(prev => !prev)}>
  <span>
    <svg viewBox={value().icon.viewBox}>
      <path d={value().icon.path} />
    </svg>
  </span>
  <span>{value().label}</span>
  <svg />
</button>

补充说明

SolidJS的响应式更新依赖于跟踪JSX中的表达式,直接插入DOM节点会绕过这种跟踪,同时触发浏览器DOM节点的唯一性限制,导致异常。通过存储可渲染的描述信息,让SolidJS正常处理渲染流程,就能避免这类问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 00:40:01