solid.js学习

For

的数据项是固定的, 索引是 Signal.

根据引用来管理dom. 原数据项引用的位置改变了, dom的位置也随之改变. 原数据项引用的内容改变了, dom的内容也随之改变

<For> is “keyed by reference”: each node that it renders is coupled to an element in the array. In other words, if an element changes placement in the array, rather than being destroyed and recreated, the corresponding node will move too and its index will change.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { render } from "solid-js/web";
import { createSignal, For } from "solid-js";

function App() {
var a = { id: "J---aiyznGQ", name: "Keyboard Cat" };
var b = { id: "J---aiyznGQ", name: "Keyboard Cat1" };
var c = { id: "J---aiyznGQ", name: "Keyboard Cat2" };

const [cats, setCats] = createSignal([a, b, c]);

return (
<ul>
<li onClick={() => { setCats([b,c,a]); }}>
使用原对象引用
</li>
<li
onClick={() => {
setCats([
{ id: "J---aiyznGQ", name: "Keyboard Cat2" },
{ id: "J---aiyznGQ", name: "Keyboard Cat" },
{ id: "J---aiyznGQ", name: "Keyboard Cat1" },
]);
}}
>
使用新对象
</li>
<For each={cats()}>
{(cat, i) => (
<li>
<a
target="_blank"
href={`https://www.youtube.com/watch?v=${cat.id}`}
>
{i() + 1}: {cat.name}
</a>
</li>
)}
</For>
</ul>
);
}

render(() => <App />, document.getElementById("app"));

在浏览器的dom对象中观察,使用原对象引用,solid只是将原dom进行移动, 而使用新对象,则会删除重新创建.

在模板里面数组的index使用signal来输出, 个人猜测这样写的原因是, 节点的复用会导致顺序的混乱, 所以index没有跟着节点走

Index

的数据项是 Signal ,并且索引是固定的。

使用位置来管理dom. 所以这里的index不再是 Signal, 而数据项是 Signal. 节点模板代码里, 数据项变更的时候, 只会更改节点的值和内容, 不再移动节点.

问题: 如果删除了数据中间第三个数据项, 会删除对应第三个的节点, 还是最后一个节点?
答案: 会删除最后一个节点, 然后更新第三个节点后的所有节点.

在solid的新旧数据比较过程中, 使用的是引用进行比较的, 但是字符串进行引用比较没有意义,因为在js中每个字符串都是单独的内存. 这样如果渲染一个字符串数组, 那每更新一个值, 都会导致整个数组的重新渲染(因为旧数组中的每个值都与新数组中的不一样).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { render } from 'solid-js/web';
import { createSignal, Index } from 'solid-js';

function App() {
const [cats, setCats] = createSignal([
{ id: 'J---aiyznGQ', name: 'Keyboard Cat' },
{ id: 'z_AbfPXTKms', name: 'Maru' },
{ id: 'OUtn3pvWmpg', name: 'Henri The Existential Cat' }
]);

return (
<ul>
<li onClick={() => { setCats(cats()); }}>
使用原对象引用
</li>
<Index each={cats()}>
{(cat, i) => (
<li>
<a target="_blank" href={`https://www.youtube.com/watch?v=${cat().id}`}>
{i + 1}: {cat().name}
</a>
</li>
)}
</Index>
</ul>
);
}

render(() => <App />, document.getElementById('app'))

组件中, 每一项的更新由自己决定, 并不会影响数组中的其他数据