在他们的渲染列表教程中,他们说:
该
<Index>组件是为这些情况提供的。根据经验,在使用基元时使用<Index>.
和
<For>关心数组中的每条数据,并且该数据的位置可以改变;<Index>关心数组中的每个索引,并且每个索引处的内容都可以更改。
这两句话对我来说都没有意义。“使用基元时”是什么意思?我总是使用数组。有人可以澄清何时使用ForvsIndex吗?
art*_*tem 21
“使用基元时”是什么意思?我总是使用数组。
它与数组元素有关 - 无论它们是基元(如字符串数组)还是对象。
简而言之,如果您有一个对象数组,请使用<For>. 如果您有字符串数组,并且数组很短,或者您从未在数组中间插入或删除元素,请使用<Index>. 否则使用<For>. 如果您不确定,请始终使用<For>.
不同之处在于数组元素更改时 DOM 的更新方式。
<For>始终检查更改之前元素是否在数组中,并移动 DOM 节点以反映元素位置的更改,而不调用回调来渲染元素(index()如果在回调中使用信号来显示项目,它也会调用信号)位置,因此所依赖的内容index()将就地更新)。如果元素以前不在数组中,则<For>调用回调来呈现更改的元素。each
因此,当您在数组中间插入一个元素时,each回调仅被调用一次 - 渲染插入的元素,并且其结果按照预期插入到数组中的 DOM 中。
<Index>不这样做 - 它更简单,它只是比较每个索引处的旧元素和新元素,如果它们不同,它会调用item()作为参数传递给each回调的信号。回调本身不会被调用,只有回调内依赖于信号的内容item()才会被更新。仅当新元素添加到数组末尾时才<Index>调用回调。each
FAQ中也对此进行了解释: for <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'))
Run Code Online (Sandbox Code Playgroud)
不同之处在于更新周期之间缓存项目的方式。
For在使用mapArray时内部使用。IndexindexArray
mapArray在处理数组或对象等引用类型时非常有用。对于原始人来说,它们没有多大意义。
映射的项目使用项目本身作为键进行缓存:
const cache = {};
cache[item] = callback();
Run Code Online (Sandbox Code Playgroud)
项目的位置对其缓存方式没有影响,因为它们的引用用作键。好处是元素位置可能会在数组内移动,但其缓存保持不变。
因此,For如果传递相同的对象,将返回先前渲染的列表项。如果传递不同的对象,即使它具有相同的值,它也会返回一个新的列表项。为什么,因为对象是通过引用比较相等性的。尽管两者具有相同的值,但它们并不相等:{name: 'John'} === {name: 'John'}。
对于indexArray,项目使用其在数组中的位置进行缓存。它更适合缓存基元,因为只要它们位于相同位置,缓存就会保持完整。
Index如果索引值有缓存元素,则返回先前呈现的列表项。这表现为细粒度的更新。对于复合值(如{name: 'John'}),属性将被重新渲染,而不是列表项。
如果您在更新周期之间传递的项目较少,则多余的项目将被清理。如果您传递更多项目,则会安装新的列表项目。
| 归档时间: |
|
| 查看次数: |
5514 次 |
| 最近记录: |