SolidJS:对于与索引
SolidJS: For vs Index
在他们的 tutorial 渲染列表中,他们说:
The <Index>
component is provided for these cases. As a rule of thumb, when working with primitives use <Index>
.
和
<For>
cares about each piece of data in your array, and the position of that data can change; <Index>
cares about each index in your array, and the content at each index can change.
这些句子对我来说都没有意义。 “使用原语时”是什么意思?我总是使用数组。有人可以澄清何时使用 For
与 Index
吗?
What does "when working with primitives" mean? I am always using an Array.
它是关于数组元素的——无论它们是基元,如在字符串数组中,还是对象。
简而言之,如果您有一个对象数组,请使用<For>
。如果您有字符串数组,并且数组很短,或者您从来没有在数组中间插入或删除元素,请使用 <Index>
。否则使用 <For>
。如果您不确定,请始终使用 <For>
.
区别在于数组元素更改时 DOM 的更新方式。
<For>
总是检查一个元素是否在变化之前在数组中,并移动 DOM 节点以反映元素位置的变化,而不调用回调来渲染元素(它将如果在回调中使用 index()
信号来显示项目位置,也会调用 index()
信号,因此依赖于 index()
的内容将被更新到位)。如果元素之前不在数组中,<For>
调用 each
回调来呈现更改后的元素。
因此,当您在数组中间插入一个元素时,each
回调仅被调用一次 - 以呈现插入的元素,并将其结果插入到 DOM 中的适当位置数组,如预期的那样。
<Index>
不会那样做 - 它更简单,它只是比较每个索引处的新旧元素,如果它们不同,它会调用作为参数传递给的 item()
信号each
回调。回调本身不会被调用,只有回调中依赖于 item()
信号的内容才会被更新。 <Index>
仅在数组末尾添加新元素时调用 each
回调。
在 FAQ 中也有解释:对于 <For>
,each
回调接收到项目值和项目位置信号。对于 <Index>
,情况正好相反 - 回调接收项目值的信号和项目位置的数字。
您可以在 Solid playground 中尝试这个示例 - 您可以打开控制台查看回调被 <For>
和 <Index>
:
调用了多少次
import { render } from 'solid-js/web';
import { createSignal, For, Index } from 'solid-js';
function ForCats() {
const [cats, setCats] = createSignal([
'Keyboard Cat',
'Maru',
'Henri The Existential Cat'
]);
setTimeout(() => setCats(['Maru', 'Keyboard Cat', 'Keyboard Cat', 'New Cat']), 2000)
return (
<ul>
<For each={cats()}>{name => {
console.log(`For: rendered ${name} whole cat`);
return <li>
<a target="_blank" href="">
1: {name}
</a>
</li>
}}</For>
</ul>
);
}
function IndexCats() {
const [cats, setCats] = createSignal([
'Keyboard Cat',
'Maru',
'Henri The Existential Cat'
]);
setTimeout(() => setCats(['Maru', 'Keyboard Cat', 'Keyboard Cat', 'New Cat']), 2000)
return (
<ul>
<Index each={cats()}>{name => {
console.log(`Index: rendered ${name()} whole cat`);
return <li>
<a target="_blank" href="">
1: {name()}
</a>
</li>
}}</Index>
</ul>
);
}
render(() => <><ForCats /> <IndexCats/ ></>, document.getElementById('app'))
For
在内部使用 mapArray
函数,并在项目更新时使用 re-renders 项目。 Index
使用 indexArray
和 re-renders 更改的位,同时保留已呈现的元素。
假设您正在呈现项目列表。 mapArray
re-renders 整个 li
而 indexArray
re-renders 表示项目值的 innerHTML。
基元或对象对项目的呈现方式没有影响。如果 item 是一个对象,mapArray
仍然是 re-renders 整个元素,indexArray
re-renders 仅更新 属性。
import { createSignal, indexArray, mapArray } from 'solid-js';
import { render } from 'solid-js/web';
const [items, setItems] = createSignal([1, 2, 3, 4]);
let x = 0;
setInterval(() => setItems([1, 2, 3, x++]), 500);
const App = () => {
return (
<div>
<ul>
{mapArray(items, (item, index) => {
// If an item updates, <li>...</li> will be re-rendered
return (
<li>#{index()}. {item} </li>
);
})}
</ul>
<ul>
{indexArray(items, (item, index) => {
// If item updates, only the value for `{item()}` will be re-rendered
return (
<li>#{index}. {item()} </li>
);
})}
</ul>
</div>
);
}
render(App, document.querySelector('#app'));
在他们的 tutorial 渲染列表中,他们说:
The
<Index>
component is provided for these cases. As a rule of thumb, when working with primitives use<Index>
.
和
<For>
cares about each piece of data in your array, and the position of that data can change;<Index>
cares about each index in your array, and the content at each index can change.
这些句子对我来说都没有意义。 “使用原语时”是什么意思?我总是使用数组。有人可以澄清何时使用 For
与 Index
吗?
What does "when working with primitives" mean? I am always using an Array.
它是关于数组元素的——无论它们是基元,如在字符串数组中,还是对象。
简而言之,如果您有一个对象数组,请使用<For>
。如果您有字符串数组,并且数组很短,或者您从来没有在数组中间插入或删除元素,请使用 <Index>
。否则使用 <For>
。如果您不确定,请始终使用 <For>
.
区别在于数组元素更改时 DOM 的更新方式。
<For>
总是检查一个元素是否在变化之前在数组中,并移动 DOM 节点以反映元素位置的变化,而不调用回调来渲染元素(它将如果在回调中使用 index()
信号来显示项目位置,也会调用 index()
信号,因此依赖于 index()
的内容将被更新到位)。如果元素之前不在数组中,<For>
调用 each
回调来呈现更改后的元素。
因此,当您在数组中间插入一个元素时,each
回调仅被调用一次 - 以呈现插入的元素,并将其结果插入到 DOM 中的适当位置数组,如预期的那样。
<Index>
不会那样做 - 它更简单,它只是比较每个索引处的新旧元素,如果它们不同,它会调用作为参数传递给的 item()
信号each
回调。回调本身不会被调用,只有回调中依赖于 item()
信号的内容才会被更新。 <Index>
仅在数组末尾添加新元素时调用 each
回调。
在 FAQ 中也有解释:对于 <For>
,each
回调接收到项目值和项目位置信号。对于 <Index>
,情况正好相反 - 回调接收项目值的信号和项目位置的数字。
您可以在 Solid playground 中尝试这个示例 - 您可以打开控制台查看回调被 <For>
和 <Index>
:
import { render } from 'solid-js/web';
import { createSignal, For, Index } from 'solid-js';
function ForCats() {
const [cats, setCats] = createSignal([
'Keyboard Cat',
'Maru',
'Henri The Existential Cat'
]);
setTimeout(() => setCats(['Maru', 'Keyboard Cat', 'Keyboard Cat', 'New Cat']), 2000)
return (
<ul>
<For each={cats()}>{name => {
console.log(`For: rendered ${name} whole cat`);
return <li>
<a target="_blank" href="">
1: {name}
</a>
</li>
}}</For>
</ul>
);
}
function IndexCats() {
const [cats, setCats] = createSignal([
'Keyboard Cat',
'Maru',
'Henri The Existential Cat'
]);
setTimeout(() => setCats(['Maru', 'Keyboard Cat', 'Keyboard Cat', 'New Cat']), 2000)
return (
<ul>
<Index each={cats()}>{name => {
console.log(`Index: rendered ${name()} whole cat`);
return <li>
<a target="_blank" href="">
1: {name()}
</a>
</li>
}}</Index>
</ul>
);
}
render(() => <><ForCats /> <IndexCats/ ></>, document.getElementById('app'))
For
在内部使用 mapArray
函数,并在项目更新时使用 re-renders 项目。 Index
使用 indexArray
和 re-renders 更改的位,同时保留已呈现的元素。
假设您正在呈现项目列表。 mapArray
re-renders 整个 li
而 indexArray
re-renders 表示项目值的 innerHTML。
基元或对象对项目的呈现方式没有影响。如果 item 是一个对象,mapArray
仍然是 re-renders 整个元素,indexArray
re-renders 仅更新 属性。
import { createSignal, indexArray, mapArray } from 'solid-js';
import { render } from 'solid-js/web';
const [items, setItems] = createSignal([1, 2, 3, 4]);
let x = 0;
setInterval(() => setItems([1, 2, 3, x++]), 500);
const App = () => {
return (
<div>
<ul>
{mapArray(items, (item, index) => {
// If an item updates, <li>...</li> will be re-rendered
return (
<li>#{index()}. {item} </li>
);
})}
</ul>
<ul>
{indexArray(items, (item, index) => {
// If item updates, only the value for `{item()}` will be re-rendered
return (
<li>#{index}. {item()} </li>
);
})}
</ul>
</div>
);
}
render(App, document.querySelector('#app'));