背景
SolidJS
- SolidJS 达到无 Virtual DOM 特性的主要方式是采用了响应性编程原理,特别是使用了细粒度的响应系统来跟踪组件的状态变化
- 每个状态变量都被看作是一个细粒度的响应信号。当状态变化时,只有依赖于这个状态的具体 UI 部分会被重新计算和更新。这意味着不需要额外的 Diff 步骤来比较整棵 DOM 树的变化,因为 SolidJS 已经精确地知道哪些部分需要更新
- 无需额外的抽象层
- 在传统拥有Virtual DOM的框架(如React和Vue)中,当组件状态更新时,整个组件或部分组件会重新渲染并且生成新的 VNode 树。然后,这个新的 VNode 树会与旧的 VNode 树进行比较(Diff 过程)
实现
function createSignal(initialValue) {
let value = initialValue;
const subscribers = new Set();
const read = () => value;
const write = (newValue) => {
if (value === newValue) return;
value = newValue;
subscribers.forEach((sub) => sub());
};
return [read, write, subscribers];
}
const subscriptions = new Map();
function createEffect(subscribeTo, callback) {
const effect = () => {
cleanup(callback());
};
subscribeTo.add(callback);
effect();
}
function cleanup(effect){
}
function Counter() {
const [count, setCount, countSubscribers] = createSignal(0);
const countElement = document.createElement('div');
createEffect(countSubscribers, () => {
countElement.textContent = `Current count is ${count()}`;
const timer = setTimeout(() => {
console.log('Effect ran after 1 second');
}, 1000);
return () => clearTimeout(timer);
});
const button = document.createElement('button');
button.textContent = 'Increment';
button.addEventListener('click', () => setCount(count() + 1));
document.body.appendChild(countElement);
document.body.appendChild(button);
}