Reactivity with SolidJS

List Reactivity

Ryan Carniato

Ryan Carniato

SolidJS Creator
Reactivity with SolidJS

Check out a free preview of the full Reactivity with SolidJS course

The "List Reactivity" Lesson is part of the full, Reactivity with SolidJS course featured in this preview video. Here's what you'd learn in this lesson:

Ryan discussed reactivity with HTML list elements. Rather than re-rendering the entire list when data changes, SolidJS provides components for iterating through the data and paginating. These components then decide what elements require updating.


Transcript from the "List Reactivity" Lesson

>> This gets us to an interesting place because if you've used frameworks like React, the thing is every framework has a syntax for handling conditionals and loops. But for Solid, because we have the single render method, it resembles more things, like Vue or Svelte, like these kinda templating languages, but we're using JSX cuz it's portable, cuz we can package it up and slice it up.

We have to give certain things special consideration, lists are one of them because, I mean, think about what happens. If you had some reactive list and you call map on it and it creates a bunch of li's, which are real DOM elements. And then someone goes and changes the list, adds an entry.

Well, a map function has no choice but to iterate the whole list again and map out the new results, so you'd end up with all new list elements. That would be incredibly expensive because, I mean, DOM creation is the most expensive thing, that's what you wanna avoid. So we technically need a helper function to do this, not, but like a special map function that goes, okay, if this item is already in the list don't recreate the DOM elements, use the existing DOM elements.

So we had a choice, and we do actually ship this helper called mapArray. But coming maybe from some other frameworks, I thought it was way more ergonomic to ship it as a component. Because the beautiful thing about components is that they compose. So essentially, if we have our list, this is very similar to the map function, we still pass what's called a render prop where we pass in a function which lets us get the list item.

But this isn't a good way of kind of wrapping up our logic, because let's say, I mean, that's For components is fine. But let's say you wanna do a virtualized list or a paginated list where you're only showing ten items at a time. Well, all you do is go import that from the library that you're gonna use.

And you're kinda back here anyway, the second that you need to actually build actual things, you're gonna find that there's gonna be components for it. Conditionals become error boundaries and suspense and layouts, loops become paginated and virtual. So we just kind of skip the step, we just start basically at the component level, and the thing is these components are not compiled.

It's not like a syntax we're looking for other than it being a JSX element. In fact, you saw all that we do with components. This is actually a runtime thing. If you don't like Solid's for loop, write your own, it's just a component. This is important. We handle thing like list by wrapping it in a getter, we handle the children by just using these simple heuristics in the JSX basically, looking at do you call function.

Then we need to access it lazily, otherwise, just inline the value. And with that, you can build all sorts of control flow components with it. I could actually use this moment to kind of show a quick demo, although we're gonna be revisiting this demo or a different version of this demo in a minute.

But I just wanted to kinda show very easily here how we can use a for, for example, to handle some props and handle a whole bunch of logic in our component to passing in theme colors and whatnot. Getting the full details of this example yet probably not terribly important, but the important thing is that we can have stuff like visibility changing what's active and complete, changing theme color on top of something.

So you can have a whole bunch of different distinct logic in a single component. And here I have this filter function called log and I have three todos on a list that are get updated. But what's really cool is, if you update, say, one item in the list, you can see that number count on the bottom and it's not gonna recall the filter cuz we're just changing the check state of one item.

It's fine grained. If we have some kinda prop coming in from above that changes the theme color, we don't have to rerun the component here. So all the changes are essentially isolated from each other because it's all based on the dependencies and there's no dependency arrays, so you don't really have to worry about it much.

What's really cool about this kind of thing is you don't see dependency arrays, there's actually no createMemo here, didn't even bother, didn't need it. There's no memo, there is no memo functions, use callback, no any of that, you literally just write the code that you need to do the update, and each piece updates independently.

>> So this is where Solid completely deviates from Vue and React, rendering is tied to respond to the data instead of rerunning the full components.
>> Yeah, that's exactly correct. And as I said, this was an older idea, and Vue has actually almost identical reactive system. But by foregoing the VDOM we get into an interesting different zone because the rendering can be just an extension of the reactive system, as long as we can assure the reactive system is consistent and dependable.

That's basically the big thing, right? Virtual DOM kinda rose up at a time period where we were worried about things like flux and we were sort of think about, unidirectional flow and a lot of the early patterns back then like MVVM, and stuff. There's a lot of like, I call them the butterfly effect where you update one thing and other things do and it bounces around.

I learned a lot from React, right? This project did not start off as trying to improve on React or replace it, it was the other way around. I was trying to improve on these kind of older patterns that were having, I say, difficulties, and React showed us what best practices look like, what good patterns look like.

That was the biggest value. There's a whole philosophy of React, I like to call it, and I feel like that's the thing to learn. It wasn't about the technology, it's about learning what it means to build user interfaces. Different projects have taken various technology pieces from React, like Vue using the virtual DOM and mixing it with reactivity.

But for me, it was never about React's technology but about their mindset. I mean, just to kind of nail this whole thing even further home, I call this the reactive advantage and it's kind of important cuz components run once, and this actually not a complete unique thing. A lot of reactive frameworks have this kind of idea where essentially your component code is like a setup function rather than a rerender function.

But what's really cool is you don't have to ever worry about the order of things or nesting or stale closures or any of those kinda details, you kinda just write the data in a kinda way that would make sense to you. And then the templates compile down to real DOM nodes, which again is really powerful as an escape hatch.

It means that at any point you can go constDiv equals JSX div, and because it runs once when you integrate it with Vanilla JavaScript or stuff like that, it's just very natural. Solid does have a syntax for refs, so you can keep your views in a nice kind of together fashion.

But it's important to understand that with such a low level of abstraction, knowing that only the smallest possible things are gonna update, you can be confident that you can just like, if you need to, go mess with those DOM nodes. And finally and most importantly, state is independent of components, right?

Component boundaries are for your sake, how you want to organize your code. They're not for performance. The performance is great regardless, right? It's about code organization. A lot of times when you use a library, you kinda have to go, I actually wanna hoist this component. And maybe no one's doing that level of optimization, but as someone who does optimization, I'm very aware of this, where it's like if you add a bunch of state here that's not related to that todo list, it's gonna cause the todo list or render over and over again unless you annotate and do all this work.

It's really cool how you can basically make this stuff independent just by the fact that it knows what's updates because of the reactive system. And honestly, the application of this goes even further than that. I mentioned I worked on the Marco team at eBay. They hired me because having this kinda knowledge of what updates and independence also solves some of the more modern problems we're facing like partial hydration and whatnot.

Because if you don't wanna ship all the JavaScript to the browser, how do you know what JavaScript you need? This is a good way. So it just kind of builds on this reactive foundation.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now