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

SolidJS:点击按钮重排信号数组后DOM未更新的问题

问题:点击按钮后SolidJS中For组件的DOM顺序未更新

我正在学习SolidJS的For流控制章节,点击按钮后控制台输出的数组顺序已经更新,但页面上的DOM元素顺序没有变化,代码如下:

import { render } from 'solid-js/web';
import { createSignal, For } from 'solid-js';

function App() {
  const [cats, setCats] = createSignal([
    { id: 'J---aiyznGQ', name: 'Keyboard Cat' },
    { id: 'z_AbfPXTKms', name: 'Maru' },
    { id: 'OUtn3pvWmpg', name: 'Henri The Existential Cat' }
  ]);

  const rearrange = () => {
    const curCats = cats();
    setCats([curCats[1],curCats[2],curCats[0]]);
    console.log(cats().map(cat => cat.name));
  };
  
  return (
    <>
      <ul>
        <For each={cats()}>{(cat, i) =>
          <li>
            <a target="_blank" href={`https://www.youtube.com/watch?v=${cat.id}`}>
              {i() + 1}: {cat.name}
            </a>
          </li>
        }</For>
      </ul>
      <button onClick={rearrange}>Rearrange</button>
    </>
  );
}

render(() => <App />, document.getElementById('app'))

问题原因

SolidJS的For组件需要接收信号本身作为each的参数,而不是调用信号获取当前值(cats())。cats()只会在组件初始渲染时获取一次数组值,之后当你调用setCats更新信号时,For组件无法感知到这个变化,因此不会重新排列DOM元素。

修复方案

将For组件的each参数从cats()改为cats,让For订阅信号的变化:

<ul>
  <For each={cats}>{(cat, i) =>
    <li>
      <a target="_blank" href={`https://www.youtube.com/watch?v=${cat.id}`}>
        {i() + 1}: {cat.name}
      </a>
    </li>
  }</For>
</ul>

这样修改后,当你点击按钮调用setCats更新数组顺序时,For组件会感知到信号的变化,自动根据新的数组顺序重新渲染DOM元素,页面上的列表顺序就会同步更新了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 15:45:32