StoresEdit this page
Similar to signals, stores are state management primitive. However, while signals manage a single piece of state, stores create a centralized location to reduce code redundancy. Within Solid, these stores can spawn a collection of reactive signals, each corresponding to a particular property which can be useful when working with complex state.
Creating a store
Store properties can be accessed directly from the state proxy through directly referencing the targeted property:
Accessing stores within a tracking scope follows a similar pattern to signals.
While signals are created using the
createSignal function and require calling the signal function to access their values, store values can be directly accessed without a function call.
This provides access to the store's value directly within a tracking scope:
Modifying store values
Updating values within a store is best accomplished using a setter provided by the
This setter allows for the modification of a specific key and its associated value, following the format
Separating read and write capabilities to a store presents a valuable debugging advantage.
It facilitates the tracking and control of which components can access or change store values.
When you create a store, it contains the initial state, but no signals are immediately created to track changes to that state. These signals are created lazily, meaning they come into existence only when you access the data within a reactive context.
When you use this data within a reactive context, such as in a template or a computed property, that is when the signals are created and dependencies are established.
For example, if you wanted to you wanted to update
store.userCount with every new user, simply writing
setStore("userCount", store.userCount.length) would not work.
Rather, you would have to add this in a tracking scope, such as within a
createEffect so that a dependency is established.
Path syntax flexibilty
Modifying a store using this method is referred to as "path syntax." In this approach, the initial arguments are used to specify the keys that lead to the target value you want to modify, while the last argument provides the new value.
String keys are used to precisely target particular values with path syntax. By specifying these exact key names, you can direclty retrieve the targeted information. However, path syntax goes beyond string keys and offers more versatility when accessing targeted values.
Instead of employing the use of just string keys, there is the option of using an array of keys. This method grants you the ability to select multiple properties within the store, facilitating accessed to nested structures. Alternatively, you can use filtering functios to access keys based on dynamic conditions or specific rules.
The flexibility in path syntax makes for efficient navigation, retrieval, and modification of data in your store, regardless of the store's complexity or the requirement for dynamic access scenarios within your application.
Modifying values in arrays
Path syntax provides a convenient way to modify arrays, making it easier to access and update their elements. Instead of relying on discovering individual indices, path syntax introduces several powerful techniques for array manipulation.
Appending new values
To append a new element to an array within a store, you specify the target array and set the index to the desired position.
For example, if you wanted to append the new element to the end of the array, you would set the index to
With path syntax, you can specify a range of indices to update or modify to target a subset of the elements within the array for modification. You can do this using an array of values:
If your store is array, you can specify a range of indices using an object with
In addition to this, including the
by key, can help you perform iterative updates within an array, which can be useful when you want to update elements at regular intervals.
This key defines the step size for index increments, similar to a
Dynamic value assignment
Path syntax also provides a way to set values within an array using functions instead of static values. These functions receive the old value as an argument, allowing you to compute the new value based on the existing one. This dynamic approach is particularly useful for complex transformations.
In scenarios where you want to update elements in an array based on a specific condition, you can pass a function as an argument. This function will act as a filter, allowing you to select elements that satisfy the condition. It receives the old value and index as arguments, providing the flexibility to make conditional updates.
When using store setters to modify objects, if a new value is an object, it will be shallow merged with the existing value. What this refers to is that the properties of the existing object will be combined with the properties of the "new" object you are setting, updating any overlapping properties with the values from the new object.
What this means, is that you can directly make the change to the store without spreading out properties of the existing user object.
Store updates with
Rather than directly modifying a store with setters, Solid has the
produce also provides a way to make changes to multiple properties at the same time which eliminates the need for multiple setter calls.
setStore do have distinct functionalities.
While both can be used to modify the state, the key distinction lies in how they handle data.
produce allows you to work with a temporary draft of the state, apply the changes, then produce a new immutable version of the store.
setStore provides a more straightforward way to update the store directly, without creating a new version.
Data integration with
When new information needs to be merged into an existing store
reconcile can be useful.
reconcile will determine the differences between new and existing data, initiating updates only when there are changed values which avoids unneccessary updates.
In this example, the store will look for the differences between the existing and incoming data sets.
'koala' - the new edition - will cause an update.
Extracting raw data with
When there is a need for dealing with data outside of a reactive context, the
unwrap utlity offers a way to transform a store to a standard object.
This conversion serves several important purposes.
Firstly, it provides a snapshot of the current state without the processing overhead associated with reactivity.
This can be useful in situations where an unaltered, non-reactive view of the data is needed.
This utility acts as a bridge to facilitate smooth integrations with external components and simplifies the incorporation of stores into various applications and workflows.
To learn more about how to use Stores in practice, visit the guide on complex state management.