Allen Wang

Allen Wang • 2025-05-18

solidJS 系列(2) - state management and props

solidJS

前言

狀態管理是處理與操作(涉及儲存與更新)整個應用程式資料的過程,在 Solid 是透過 signal 與 subscriber 來實作,當 signal 改變有追蹤到的地方就會重新執行它的 getter function。在 React 是透過 useState hook 來實作,當 state 改變時整個元件都會重新渲染,因此兩者就有了更新粒度的差異。 Solid 的核心是反應系統( Reactivity System ),它並不是透過整個元件的重新渲染來更新畫面,而是以細緻的追蹤機制,讓程式知道哪一行 code 依賴了哪一個 signal,然後只重新執行那一行。

useState and createSignal比較

項目React useStateSolidJS createSignal
回傳內容[value, setValue][getter, setter]
使用方式count 是值count 是函數(getter)
更新後行為觸發整個元件重新執行只觸發使用 count() 的地方
初次執行 JSX每次狀態變化重新跑只執行一次(JSX 是靜態的)
性能表現依賴 Virtual DOM diff直接操作 DOM

React:useState

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  console.log('每次'); // 每次點擊都會 log 出來

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

Solid : createSignal

適合儲存基本型別的資料

function Counter() {
  const [count, setCount] = createSignal(0);

  console.log('第一次'); // 只會在初始時執行一次

  return (
    <div>
      <p>Count: {count()}</p>
      <button onClick={() => setCount(count() + 1)}>Increment</button>
    </div>
  );
}

createStore

createSignal 很像但是它是特別設計來儲存物件陣列等複雜資料,這個還沒弄很清楚有空在補

props

需要特別注意的是 solid 所傳遞的 props 寫法上不建議直接解構,

React

// React Component (可直接解構)
function Greeting({ name }) {
  return <h1>Hello, {name}!</h1>;
}

// 使用
<Greeting name="Allen" />;
// 父元件
function Parent() {
  const [person, setPerson] = createSignal({ name: 'Allen', age: 30 });

  setTimeout(() => {
    setPerson({ name: 'Apple', age: 40 }); // 整個物件被替換
  }, 2000);

  return <Child person={person} />;
}

// 子元件
function Child(props) {
  // 這裡解構出來的是 person function
  const { person } = props;

  // 這裡再解構 person() 返回的物件
  const { age } = person(); // 這樣會斷開響應連接!

  return <div>Age: {age}</div>; // 不會變成 Apple 不會更新
}

總結

在 React 中,狀態變了就會觸發整個元件重新執行; 在 Solid 中,只有用到那個狀態的「那一行」才會重新執行。

從原本可解構的寫法來看可能會不太習慣,可以記住在傳遞 signal 時候永遠直接訪問不要解構來避免錯誤