在他们用于呈现列表的教程中,他们说:
为这些情况提供了
<Index>组件。经验法则是,在使用原语时使用<Index>。
和
<For>关心数组中的每一块数据,数据的位置可能发生变化;<Index>关心数组中的每个索引,而每个索引的内容可能发生变化。
这两句话对我来说都没有意义。“使用原语”意味着什么?我总是使用数组。有人能澄清一下何时使用For和Index吗?
发布于 2022-01-23 08:31:38
“使用原语”意味着什么?我总是使用数组。
它涉及数组元素--无论它们是原语,如字符串数组中的元素,还是对象中的元素。
简而言之,如果您有一个对象数组,请使用<For>。如果您有和数组的字符串,并且数组是短的,或者您从来没有在数组中间插入或删除元素,那么使用<Index>。否则使用<For>。如果您不确定,请始终使用<For>。
区别在于更改数组元素时如何更新DOM。
<For>总是在更改之前检查元素是否在数组中,并移动DOM节点以反映元素位置的变化,而不调用回调来呈现元素(如果在回调中使用index()信号来显示项位置,那么依赖于index()的内容将被更新到位)。如果元素以前不在数组中,则<For>调用each回调以呈现已更改的元素。
因此,当您在数组中间插入一个元素时,只调用一次each回调来呈现插入的元素,其结果将按预期的方式插入到数组中的DOM中。
<Index>没有这样做--它要简单得多,它只是在每个索引上比较新旧元素,如果它们不同,就调用作为参数传递给each回调的item()信号。回调本身不会被调用,只有依赖于item()信号的回调中的内容才会被更新。只有在数组末尾添加新元素时,<Index>才会调用each回调。
在常见问题中也解释了这一点:对于<For>,each回调接收到一个项值和一个项位置信号。对于<Index>,则相反--回调接收项值的信号和项位置的数字。
您可以在实心操场中尝试这个示例??您可以打开控制台,查看<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'))发布于 2022-05-24 16:25:11
For在内部使用mapArray函数,并在项目更新时重新呈现项。Index使用indexArray并重新呈现已更改的位,同时保留已呈现的元素。
假设您正在呈现一个项目列表。mapArray重新呈现整个li,而indexArray重新呈现表示项的值的innerHTML。
作为原语或对象对项目的呈现方式没有任何影响。如果item是一个对象,mapArray仍然重新呈现整个元素,indexArray只重新呈现更新的属性。
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'));https://stackoverflow.com/questions/70819075
复制相似问题