Understanding behavior of rendering list of objects using For

I have an array of User objects ({id, name, age, hobbies}) that I would like to render into a list of HTML div elements that display the contents of the objects (fields and associated values). I know I can use the built-in For element to render this list. I need help understanding the differences between using signals vs stores in terms of whether or not the entire list of HTML div elements will be re-rendered in the following scenarios: 1. Insert a new User object in the middle of the array 2. Append a new User object to the end of the array elements re-rendered? What if I use stores instead? 3. Update the age field of a specific User object within the array (ex. id="abc123") 4. Append a new value to the hobbies array of a specific User object within the array.
5 Replies
ladybluenotes
ladybluenotes3mo ago
I’m a bit confused about what you’re asking. You’re mentioned stores and the For - both can be used together so it kinda depends what you need specifically. However, have you had a chance to read the docs on stores? It might help address the questions about them (https://docs.solidjs.com/concepts/stores). Stores are useful when you don’t want to create a bunch of individual signals for something (how i think about it at least). All of what you mention can be handled via stores and I believe the docs address those specific concerns(that being said if you find you need clarification please let us know!) As far as the list rendering, if your list length will be changing (like you’re adding/removing more than just editing) it’s recommended to use For to display. That being said there is Index to limit re-renders, it will limit the re-renders bc it’s more focused on the content over the list itself. As an example, if you had form inputs in a For list, with every key stroke you’d be re-rendering whereas if you were using Index you wouldn’t. So, tbh, a bit situational depending on what your specific needs are for that (more info here - https://docs.solidjs.com/concepts/control-flow/list-rendering) Does that answer your question?
goose
goose3mo ago
TLDR; you need a store for that. Signals are atomic: they don't mutate previous data, but replace it completely with every change. That's okay for primitives like number or strings, but for a list of objects, it will replace all the list with a new one on every change, and thus, trigger a re-render of all elements, which is not good. Stores on the other hand, provide a setter that allow fine-grained updates on deeply nested array and objects, and will trigger re-renders only on the fields that need to be updated in the UI. Check out the docs on how to update stuff in your listed scenarios with stores: https://docs.solidjs.com/concepts/stores#modifying-values-in-arrays
Stores - Solid Docs
Documentation for SolidJS, the signals-powered UI framework
goose
goose3mo ago
Kind of not true, the list is new, but the objects are the same, so nothing will change/re-render.
Yeah, you're right, For tracks the object references. So it depends of how you clone the previous array into the new one to update the signal. Doing setUsers([...users()]) or setUsers(Array.from(users())) will preserve the previous references, but setUsers(structuredClone(users())) will not. Thanks for the observation!
FatFreeButter
FatFreeButterOP3mo ago
Thanks all. This was super helpful.
Doing setUsers([...users()]) or setUsers(Array.from(users())) will preserve the previous references
Are you saying that either of these statements will not trigger a re-render? If so, it's good to know that Solid.js is smart enough to ignore array references and to instead look at references of the array elements.
goose
goose3mo ago
Yes. Solid will track the references of objects within signals to emit changes or not, but is safer to use a store for those, and signals for primitives (numbers, strings, booleans).

Did you find this page helpful?