列表渲染 #

一、列表渲染概述 #

1.1 Solid 的列表渲染方式 #

Solid 提供了专门的组件来高效渲染列表。

方式 说明 适用场景
For 基于 key 的高效更新 对象数组
Index 基于索引的更新 原始值数组
map 原生数组方法 简单静态列表

二、For 组件 #

2.1 基本用法 #

jsx
import { For } from 'solid-js';

function UserList() {
  const [users, setUsers] = createSignal([
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' },
    { id: 3, name: 'Charlie' }
  ]);

  return (
    <ul>
      <For each={users()}>
        {(user) => <li>{user.name}</li>}
      </For>
    </ul>
  );
}

2.2 访问索引 #

jsx
function NumberedList() {
  const [items, setItems] = createSignal(['Apple', 'Banana', 'Orange']);

  return (
    <ol>
      <For each={items()}>
        {(item, index) => (
          <li>{index() + 1}. {item}</li>
        )}
      </For>
    </ol>
  );
}

2.3 响应式更新 #

jsx
function DynamicList() {
  const [items, setItems] = createSignal([
    { id: 1, value: 'First' },
    { id: 2, value: 'Second' }
  ]);

  const addItem = () => {
    setItems(prev => [...prev, { id: Date.now(), value: 'New' }]);
  };

  const removeItem = (id) => {
    setItems(prev => prev.filter(item => item.id !== id));
  };

  return (
    <div>
      <button onClick={addItem}>Add Item</button>
      <ul>
        <For each={items()}>
          {(item) => (
            <li>
              {item.value}
              <button onClick={() => removeItem(item.id)}>×</button>
            </li>
          )}
        </For>
      </ul>
    </div>
  );
}

三、Index 组件 #

3.1 基本用法 #

jsx
import { Index } from 'solid-js';

function NumberList() {
  const [numbers, setNumbers] = createSignal([1, 2, 3, 4, 5]);

  return (
    <ul>
      <Index each={numbers()}>
        {(number, index) => (
          <li>Index {index}: {number()}</li>
        )}
      </Index>
    </ul>
  );
}

3.2 For vs Index #

jsx
// For:值是固定的,索引是 Signal
<For each={items()}>
  {(item, index) => (
    <div>
      Item: {item.name} {/* 固定值 */}
      Index: {index()}  {/* Signal */}
    </div>
  )}
</For>

// Index:索引是固定的,值是 Signal
<Index each={items()}>
  {(item, index) => (
    <div>
      Item: {item()}    {/* Signal */}
      Index: {index}    {/* 固定值 */}
    </div>
  )}
</Index>

四、性能优化 #

4.1 选择正确的组件 #

数据类型 推荐 原因
对象数组 For 基于 key 保持状态
原始值数组 Index 基于索引更新
静态列表 map 简单直接

4.2 使用 createMemo 缓存 #

jsx
function FilteredList() {
  const [items, setItems] = createSignal([...]);
  const [filter, setFilter] = createSignal('');

  // 缓存过滤结果
  const filteredItems = createMemo(() => {
    const f = filter().toLowerCase();
    return items().filter(item => 
      item.name.toLowerCase().includes(f)
    );
  });

  return (
    <div>
      <input 
        value={filter()}
        onInput={(e) => setFilter(e.target.value)}
      />
      <ul>
        <For each={filteredItems()}>
          {(item) => <li>{item.name}</li>}
        </For>
      </ul>
    </div>
  );
}

五、总结 #

5.1 API 选择 #

  • For:对象数组,需要保持组件状态
  • Index:原始值数组,可编辑的简单列表
  • map:静态列表,不需要响应式更新

5.2 最佳实践 #

  1. 对象数组优先使用 For
  2. 使用 createMemo 缓存计算结果
  3. 大型列表考虑虚拟滚动
  4. 确保 key 唯一且稳定
最后更新:2026-03-28