import {Aside} from "~/components/configurable/Aside"
Using Stores
The stores API are available at solid-js/stores. They allow the creation of stores: proxy objects that allow a tree of signals to be independently tracked and modified.
importtype{StoreNode,Store,SetStoreFunction}from"solid-js/store";functioncreateStore<TextendsStoreNode>(state:T|Store<T>):[get:Store<T>,set:SetStoreFunction<T>];typeStore<T>=T;// conceptually readonly, but not typed as such
The create function takes an initial state, wraps it in a store, and returns a readonly proxy object and a setter function.
123456789
const[state,setState]=createStore(initialValue);// read valuestate.someValue;// set valuesetState({merge:"thisValue"});setState("path","to","value",newValue);
As proxies, store objects only track when a property is accessed.
When nested objects are accessed, stores will produce nested store objects, and this applies all the way down the tree. However, this only applies to arrays and plain objects. Classes are not wrapped, so objects like Date, HTMLElement, RegExp, Map, Set won't be granularly reactive as properties on a store.
As of version 1.4.0, the top level state object can be an array. In prior versions, you need to create an object to wrap the array:
1 2 3 4 5 6 7 8 910111213141516
//After Solid 1.4.0
const [todos, setTodos] = createStore([
{ id: 1, title: "Thing I have to do", done: false },
{ id: 2, title: "Learn a New Framework", done: false },
]);
...
<For each={todos}>{todo => <Todo todo={todo} />}</For>;
//Prior to Solid 1.4.0
const [state, setState] = createStore({
todos: [
{ id: 1, title: "Thing I have to do", done: false },
{ id: 2, title: "Learn a New Framework", done: false },
],
});
<For each={state.todos}>{(todo) => <Todo todo={todo} />}<For>;
Note that modifying an array inside a store will not trigger computations that subscribe to the array directly. For example:
1 2 3 4 5 6 7 8 91011121314
// After Solid 1.4.0createEffect(()=>{// This will not get triggered because we've subscribed to the array itself.console.log(todos);});setTodos(todos.length,{id:3});// Prior to Solid 1.4.0createEffect(()=>{// This will not get triggered because we've subscribed to the array itself.console.log(state.todos);});setState(todos,state.todos.length,{id:3});
However, subscribing to any signals that change inside the array will trigger those computations.
1 2 3 4 5 6 7 8 910111213141516
// After Solid 1.4.0createEffect(()=>{// This will be triggered because we've subscribed to the actual signals in the array.console.log([...todos]);console.log(todos[2])// Or we can subscribe only to a specific one.});setTodos(todos.length,{id:3});// Prior to Solid 1.4.0createEffect(()=>{// This will be triggered because we've subscribed to the actual signals in the array.console.log([...state.todos]);console.log(state.todos[2])// Or we can subscribe only to a specific one.});setState(todos,state.todos.length,{id:3});
Changes can take the form of function that passes previous state and returns new state or a value. Objects are always shallowly merged. Set values to undefined to delete them from the Store.
It supports paths including key arrays, object ranges, and filter functions.
setState also supports nested setting where you can indicate the path to the change. When nested the state you are updating may be other non Object values. Objects are still merged but other values (including Arrays) are replaced.
Path can be a string of keys, array of keys, iterating objects (from, to), or filter functions. This gives incredible expressive power to describe state changes.