Reputation: 3474
My app has a list of items where each item is an object, and one of the items can be in active state. I'm using SolidJS.
My first idea was to represent the whole state of the app in a store:
const [store, setStore] = createStore({
items: [
{ id: 1, name: "Apple" },
{ id: 2, name: "Banana" }
],
activeItem: null
});
This is not working, because when I change the activeItem, it modifies the previously active item.
setStore('activeItem', store.items[0]);
setStore('activeItem', store.items[1]); // This modifies the ID and Name of store.items[0]. We end up with an array with two bananas.
What are good ways to keep an active item for a list of items in SolidJS?
Upvotes: -1
Views: 139
Reputation: 13698
Solid provides the createSelector
function for this purpose.
You can use item id, index number or even the item itself to keep track the selected item. For your use case, id
property is good enough.
createSelector
takes a signal, creates an internal computation to monitor the signal, and returns a function. The returned function takes a value and returns a boolean, indicating whether the provided value is equal to the one stored in the signal:
import { createSelector } from "solid-js";
import { createStore } from "solid-js/store";
import { render } from "solid-js/web";
const App = () => {
const [store, setStore] = createStore({
activeItem: 0,
items: [
{ id: 1, name: "Apple" },
{ id: 2, name: "Banana" },
{ id: 3, name: "Orange" },
],
});
const isSelected = createSelector(() => store.activeItem);
return (
<div>
<div>Selected ID: {store.activeItem}</div>
<ul>
{store.items.map((item) => {
return (
<li onclick={() => setStore('activeItem', item.id)}>
<input type="checkbox" checked={isSelected(item.id)} />
{item.name}
</li>
)
})}
</ul>
</div>
);
}
render(() => <App />, document.body);
Here is a live demo: https://playground.solidjs.com/anonymous/0bab81bd-24a3-4a5e-ab89-795bf46d1916
Listeners are captured and cached by the value they check. When the original signal updates, the value corresponding to each cached-key is re-evaluated, notifying the listener that is registered under an updated key. This makes the update operations O(1) instead of O(n).
createSelector
supports custom comparator function in case you need to control the selection logic. There are a few more details, like selecting multiple items, or using an object for the selection. You can check the API: https://docs.solidjs.com/reference/secondary-primitives/create-selector
Disclaimmer: I am the author of SolidJS: The Complete Guide. I copy parts of this answer from the book. If you're into SolidJS, check out 👉 https://solid.courses/p/solidjs-the-complete-guide/ — It will help you greatly to cut down on the time to master SolidJS.
Upvotes: 2