📡 Signals 信号
Signals 是 SolidJS 响应式系统的核心:
javascript
import { createSignal } from 'solid-js';
// 创建信号
const [count, setCount] = createSignal(0);
// 读取值(调用函数)
console.log(count()); // 0
// 设置值
setCount(1);
setCount(c => c + 1); // 函数式更新
💡 为什么是函数调用?
使用 count() 而非 count,让 SolidJS 能够精确追踪依赖关系。当信号在 Effect 或 Memo 中被访问时,自动建立订阅。
🧮 计算属性
javascript
import { createSignal, createMemo } from 'solid-js';
const [firstName, setFirstName] = createSignal('John');
const [lastName, setLastName] = createSignal('Doe');
// 自动追踪依赖,惰性求值
const fullName = createMemo(() => {
console.log('Computing...'); // 只在依赖变化时执行
return `${firstName()} ${lastName()}`;
});
console.log(fullName()); // "John Doe"
console.log(fullName()); // 缓存,不重新计算
setFirstName('Jane');
console.log(fullName()); // "Jane Doe",重新计算
🔄 副作用 Effects
javascript
import { createSignal, createEffect } from 'solid-js';
const [count, setCount] = createSignal(0);
// 自动追踪依赖
createEffect(() => {
console.log(`Count is ${count()}`);
// 依赖: count
});
// count 变化时自动执行
setCount(1); // "Count is 1"
清理副作用
javascript
createEffect(() => {
const timer = setInterval(() => {
console.log('Tick');
}, 1000);
// 返回清理函数
return () => clearInterval(timer);
});
🏪 Store 深层响应式
javascript
import { createStore, produce } from 'solid-js/store';
// 创建深层响应式对象
const [store, setStore] = createStore({
user: {
name: 'John',
todos: [
{ id: 1, text: 'Learn Solid', done: false }
]
}
});
// 读取
console.log(store.user.name);
// 更新嵌套属性
setStore('user', 'name', 'Jane');
// 数组操作
setStore('user', 'todos', 0, 'done', true);
// 使用 Immer 风格
setStore(produce(s => {
s.user.todos.push({ id: 2, text: 'Build app', done: false });
}));
🌐 异步数据 createResource
jsx
import { createResource, Suspense } from 'solid-js';
// 数据获取函数
const fetchUser = async (id) => {
const res = await fetch(`/api/users/${id}`);
return res.json();
};
function UserProfile({ id }) {
// 创建资源
const [user] = createResource(() => id(), fetchUser);
return (
<Suspense fallback={<p>Loading...</p>}>
{user() && (
<div>
<h1>{user().name}</h1>
<p>{user().email}</p>
</div>
)}
</Suspense>
);
}
⚡ 无虚拟 DOM
SolidJS 编译时将 JSX 转换为真实 DOM 操作:
jsx
// 源代码
function Counter() {
const [count, setCount] = createSignal(0);
return <div>{count()}</div>;
}
// 编译后(简化)
function Counter() {
const [count, setCount] = createSignal(0);
const _el$ = document.createElement('div');
insert(_el$, count);
return _el$;
}
🎯 优势
- 无 Diff 算法开销
- 精确更新,不重渲染组件
- 更少的内存占用
- 更快的首次渲染