Control Flow

列表渲染

编辑此页面

列表渲染用于渲染数据集合(例如数组或对象)。

Solid 提供了两种渲染列表的方式:<For><Index> 组件。这两个组件都可以遍历数据集合生成元素,但它们适合不同的场景。


<For>

<For> 是一个循环组件,允许您根据数组或对象的内容渲染元素。该组件被设计用于复杂的数据结构,例如对象数组,其中列表的顺序和长度可能会频繁更改。

<For> 的唯一属性是 each ,用于指定要循环的数据集合。此属性需要一个数组,如果使用对象,需要先通过 Object.entriesObject.values 等方法转换为数组。

import { For } from "solid-js"
<For each={data()}>
{(item, index) =>
// 每个元素的渲染逻辑
}
</For>

<For> 标签之间,组件需要一个回调函数,该函数将指定如何渲染数据集合中的每个条目。此结构类似于 JavaScript 的 map 方法中使用的回调。

该函数接收两个参数:

  • item: 表示正在渲染的数据集合中的当前条目。
  • index: 表示当前条目的索引。

您可以访问当前的 itemindex 来动态设置 JSX 元素的属性或内容。 index 是一个信号,必须作为函数调用才能获取其值。

<For each={data()}>
{(item, index) => (
<li
style={{
color: index() % 2 === 0 ? "red" : "blue",
}}
>
{item.name}
</li>
)}
</For>

Index

<Index><For> 类似,也是一个循环组件,允许您根据数组或对象的内容渲染元素。但是,当列表的顺序和长度保持稳定,但内容可能频繁更改时,<Index> 是更好的选择,因为它会减少重新渲染的次数。

import { Index } from "solid-js"
<Index each={data()}>
{(item, index) => (
// 每个元素的渲染逻辑
)}
</Index>

<For> 组件类似, <Index> 接受名为 each 的单个属性,用于指定要循环遍历的结构。

<For>中,index 是一个信号,但在 <Index> 中是固定的。这是因为 <Index> 更关心带有索引的元素,因此,item是一个信号,允许每个索引的内容更改而无需重新渲染,同时索引保持固定。

import { Index } from "solid-js";
<Index each={data()}>
{(item, index) => (
<li>
{item().name} - {item().completed}
</li>
)}
</Index>;

<Index> vs <For>

<For> 用于列表的顺序和长度可能频繁变化的情况。当 <For> 中的列表值发生变化时,整个列表将重新渲染。但是,如果数组发生更改,例如元素移动位置,<For> 将通过简单地移动相应的 DOM 节点并更新索引来管理这种情况。

<Index> 用于当列表的顺序和长度保持稳定,但内容可能频繁变化时。当 <Index> 中的列表值发生变化时,仅更新指定索引处的内容。

When to use <For>

在不需要信号、嵌套循环或动态列表的情况下,<For> 是最佳选择。例如,在创建静态元素列表(例如链接列表)时,<For> 是最好的选择。这是因为它只会修改列表中元素的索引,而不会重新渲染整个列表。

import { createSignal, For } from "solid-js";
function StringList() {
const [items, setItems] = createSignal(["Item 1", "Item 2", "Item 3"]);
return (
<ul>
<input
type="text"
onInput={(e) => {
// 向列表添加新的条目
}}
/>
<For each={items()}>
{(item, index) => (
<li>
{item} - {index()}
</li>
)}
</For>
</ul>
);
}

如果您正在使用信号、JavaScript 原始值(例如字符串和数字)或输入字段,<Index> 是更好的选择。如果您使用 <For> ,则当值更改时,即使列表的长度保持不变,整个列表也会重新渲染。而 <Index> 将更新指定索引处的内容,列表的其余部分保持不变。

import { createSignal, Index } from "solid-js";
function FormList() {
const [inputs, setInputs] = createSignal(["input1", "input2", "input3"]);
return (
<form>
<Index each={inputs()}>
{(input, index) => (
<input
type="text"
value={input()}
onInput={(e) => {
// 更新 input 值
}}
/>
)}
</Index>
</form>
);
}
报告此页面问题