Store状态管理 #

一、Store 概述 #

1.1 什么是 Store #

Store 是 Solid 提供的深层响应式状态管理方案,适合管理复杂的嵌套对象状态。

jsx
import { createStore } from 'solid-js/store';

const [state, setState] = createStore({
  user: {
    name: 'Alice',
    preferences: {
      theme: 'dark'
    }
  },
  items: []
});

1.2 Store vs Signal #

特性 Signal Store
适用场景 简单状态 复杂嵌套状态
更新粒度 整体替换 精确路径更新
嵌套支持 需要手动处理 原生支持
性能 简单场景更好 复杂场景更优

二、基本用法 #

2.1 创建 Store #

jsx
import { createStore } from 'solid-js/store';

function TodoApp() {
  const [state, setState] = createStore({
    todos: [],
    filter: 'all'
  });

  return (
    <div>
      <p>Filter: {state.filter}</p>
      <ul>
        <For each={state.todos}>
          {(todo) => <li>{todo.text}</li>}
        </For>
      </ul>
    </div>
  );
}

2.2 读取状态 #

jsx
// 直接访问属性
console.log(state.filter);
console.log(state.todos[0].text);

// 在组件中使用
function Display() {
  return <p>{state.user.name}</p>;
}

2.3 更新状态 #

jsx
// 更新单个属性
setState('filter', 'completed');

// 更新嵌套属性
setState('user', 'name', 'Bob');

// 更新数组元素
setState('todos', 0, 'done', true);

// 使用函数更新
setState('todos', todos => [...todos, { id: 3, text: 'New' }]);

// 批量更新
setState({
  filter: 'all',
  user: { name: 'Charlie' }
});

三、produce 函数 #

3.1 可变式更新 #

produce 允许以可变方式更新状态:

jsx
import { createStore, produce } from 'solid-js/store';

const [state, setState] = createStore({
  items: [1, 2, 3]
});

// 使用 produce 进行可变更新
setState(produce(s => {
  s.items.push(4);
  s.items[0] = 10;
}));

3.2 嵌套更新 #

jsx
setState('todos', produce(todos => {
  todos.push({ id: 3, text: 'New task' });
  todos[0].completed = true;
}));

四、实际应用 #

4.1 表单状态管理 #

jsx
function FormStore() {
  const [form, setForm] = createStore({
    values: {
      email: '',
      password: ''
    },
    errors: {},
    touched: {}
  });

  const setFieldValue = (field, value) => {
    setForm('values', field, value);
  };

  const setFieldError = (field, error) => {
    setForm('errors', field, error);
  };

  const setFieldTouched = (field) => {
    setForm('touched', field, true);
  };

  return (
    <form>
      <input
        value={form.values.email}
        onInput={(e) => setFieldValue('email', e.target.value)}
        onBlur={() => setFieldTouched('email')}
      />
      <Show when={form.touched.email && form.errors.email}>
        <span class="error">{form.errors.email}</span>
      </Show>
    </form>
  );
}

4.2 购物车 #

jsx
function ShoppingCart() {
  const [cart, setCart] = createStore({
    items: [],
    discount: 0
  });

  const addItem = (product) => {
    setCart(produce(c => {
      const existing = c.items.find(i => i.id === product.id);
      if (existing) {
        existing.quantity += 1;
      } else {
        c.items.push({ ...product, quantity: 1 });
      }
    }));
  };

  const removeItem = (id) => {
    setCart('items', produce(items => {
      const index = items.findIndex(i => i.id === id);
      if (index > -1) items.splice(index, 1);
    }));
  };

  const updateQuantity = (id, quantity) => {
    setCart('items', i => i.id === id, 'quantity', quantity);
  };

  return (
    <div>
      <For each={cart.items}>
        {(item) => (
          <div>
            <span>{item.name}</span>
            <input
              type="number"
              value={item.quantity}
              onChange={(e) => updateQuantity(item.id, parseInt(e.target.value))}
            />
            <button onClick={() => removeItem(item.id)}>Remove</button>
          </div>
        )}
      </For>
    </div>
  );
}

五、最佳实践 #

5.1 模块化 Store #

jsx
// stores/userStore.js
import { createStore } from 'solid-js/store';

const [state, setState] = createStore({
  user: null,
  loading: false,
  error: null
});

export const userStore = {
  state,
  login: async (credentials) => {
    setState('loading', true);
    try {
      const user = await loginApi(credentials);
      setState({ user, loading: false, error: null });
    } catch (error) {
      setState({ loading: false, error: error.message });
    }
  },
  logout: () => {
    setState('user', null);
  }
};

5.2 使用 produce 简化更新 #

jsx
// 推荐:使用 produce
setState(produce(s => {
  s.items.push(newItem);
  s.count += 1;
}));

// 不推荐:多次 setState
setState('items', items => [...items, newItem]);
setState('count', c => c + 1);

六、总结 #

6.1 Store API #

API 说明
createStore(initial) 创建 Store
state.key 读取状态
setState(path, value) 更新状态
produce(fn) 可变式更新

6.2 最佳实践 #

  1. 复杂嵌套状态使用 Store
  2. 简单状态使用 Signal
  3. 使用 produce 简化更新逻辑
  4. 模块化状态管理
最后更新:2026-03-28