📡 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 算法开销
  • 精确更新,不重渲染组件
  • 更少的内存占用
  • 更快的首次渲染