Reactivity with SolidJS

Reactivity with Vanilla JavaScript

Ryan Carniato

Ryan Carniato

SolidJS Creator
Reactivity with SolidJS

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

The "Reactivity with Vanilla JavaScript" 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 demonstrates how reactivity can be used to update DOM elements. A count signal is create and an h1 element's text content is updated inside an effect when a button is clicked.


Transcript from the "Reactivity with Vanilla JavaScript" Lesson

>> Reactivity in itself is not something that is that unique, you've seen this in other frameworks, but for Solid, it has a special role. Basically armed with this tool, we can do a lot more than state management. I know we've been doing console logs and you can maybe kind of picture, you can put some global state in there and trigger your components to rerender but where a lot of the uniqueness all comes in is I asked the question, what if our renderer could just be the reactive system?

Like what if we don't need a virtual DOM or any other kind of mechanism to actually update our view? Rech Harris, from Svelte, once famously said that frameworks aren't there to organize your code but to organize your mind. That was his saying and that's actually how I feel about components in the introduction I mentioned, that components are kind of this runtime overhead that doesn't actually necessarily need to be.

And as I've mentioned before, reactive libraries have had some issues in the past, but luckily a lot has happened in the last decade so, even if you don't believe me you don't have to. We've seen this kind of natural evolution, first with things like MobX ensuring predictable execution using topic graphical sorting.

They ensure that functions run exactly when you expect them to run and only run once. And similarly, the old system just kind of went crazy. Like the one we implemented just now, like you just update stuff, it just runs right away, there's no batching, no scheduling but we can learn from what others have done and add the ability to schedule when our side effects actually happen.

And finally, even though we didn't implement this in our reactive system, the way we wrote it there, that effect never goes away and we don't want to manage all of that. Classically, you'll find in a lot of frameworks, their createEffect actually returns to dispose function and you have to actually call dispose manually if you want to get rid of it.

You don't see it a lot in stuff like MobX because they tied into the component life cycle but for us, one of the key revelations came from a library called SJS in which in the same way that we implemented that cleanup in the last step, it doesn't have to only clean up dependencies, it can actually clean up child nested effects.

So whenever that reruns, we just can automatically clean any children, get rid of any nested effects or computations and that way we get rid of a lot of the ugly bookkeeping, basically create a render with reactivity in mind instead of just trying to apply reactivity to an existing render.

I'll be talking in a moment about scheduling here because I think many people are familiar with React and I think this will kind of help you kind of map the model over, right? Because React has kind of like four stages of rendering. And I'm not talking about initial render, I'm talking about from the point of view of an update.

You set state initially, that's the event that comes in you know, someone clicks a button or does something, and then it runs the component tree. It goes, okay, from here down, I need to rerun the components. And we've seen this expressed as like view is a function of state, but more specifically it's VDOM is a function of state.

They create a virtual DOM representation by rerendering all your components and then they take that tree and Diff it against another tree and then apply the little updates that happen, and then once it's all done it runs everyone's favorite function. Solid's actually fairly similar in that when the event happens we call setSignal and then the pure computation happens, all the memos or derived values run and then you as the end user don't use these often but our renderer actually uses something called createRenderEffect, which is essentially an effect that's made for updating the DOM during the rendering, and then we run createEffect.

This kind of timeline is actually very analogous. It's the reason why we can do scheduling, why we can do concurrent rendering, why we can do basically everything that a VDOM can do, it's because the scheduling is actually almost the same kind of concept But I think this is another opportunity to get into playing around with the code again.

I know we just did that but this is so much easier to show than to explain so this time, we're not going to be creating the reactive system ourselves. We're going to use Solid's actual reactive system. I'm going to go back into the playground, and this time I'm going to make a new one and it's kind of funny to me and it makes a lot of sense.

We always teach reactivity using console logs like, Hello World, Hi. And it's a good place to start as it really makes the concept easy to see and we see people doing it for state updates, but I want to do something a little bit more substantial here. So what I'm going to do is I'm going to create a signal and I'm going to import it this time from Solid Js.

This time it actually being in the playground is actually important. Of course the playground is being fun. Okay, there we go. And I'm going to just make a variable. I'm going to use count for, again, because you're probably tired of counters by now, but counters are used in these demos for a reason because they're about the most simple example you can come up with.

And this time when we create an effect, what if instead of console logging something, we did something a little bit more substantial? And by that what I mean is, let's pretend that I create an h1 element. I'm going to use the most powerful JavaScript framework here, vanilla Js and I'm going to create an h1.

And because our effect can really do anything I'm just going to go h1.textcontent and this is a real DOM node. I'm going to just set that text content to, I don't know, the count is the count whatever, okay, call our signal. And I'm going to attach it to the DOM but because of this environments always rerunning, I'm actually going to do a little hack here.

Without using Solid's imports I'm actually going to clear the body every time the thing updates. It's not hugely important but then we can append our h1 and document.body and we see the count is zero, okay? Of course, this doesn't do very much so maybe we should actually update the count to something else like the count is 1, but this happens a little bit too fast, right?

If I refresh this you're going to be like okay, on the count it's 1. This is happening immediately so let's make some more DOM elements. Let's make a button maybe, so I'm going to go document.createElement, button, all right? And let's set the text for that button like, I know, click me and then let's go button.onclick equals a function, arrow function.

And I'm going to do setCount equals count plus one, okay? And then I'm going to get rid of this one. And I guess we need to attach our button to the DOM, so lets add the button. Okay, sweet. And if you're getting jQuery vibes here, that's perfectly fine, but we have a working counter, right?

All that's happening is every time we click our button we're just calling setCount, count plus one and it's replacing the text in in here, right? So yeah, using reactivity to update the DOM is something that is fairly simple to do, you don't need a framework or anything.

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