Web Components and You Part 2: Attributes and Reactivity

Published 2024-03-01, About 4 minute read.

HTML is powerful because it has attributes to customize elements. You can specify why type of input by include type="_type_"` inside the <input /> tag. You can set properties like whether a checkbox is checked by using the checked boolean attribute.

So of course custom elements are going to use attributes. They also allow a component to react when attributes change.

First, take a look at accessing a simple attribute "my-attr":

We can access attributes by using element.getAttributes('attr'), and in this example we're just putting it in the DOM.

What happens if we change the attribute?

If you open dev tools and manually change the value of the attribute you'll see that it doesn't automatically update...

We have to do more work to wire up reactivity.

An important note here...

If you're used to using any framework, this may be something you've never had to think about. In HTML, the attributes we use always have a string value- which is why weird things happen when you have a checkbox and you say disabled="false" and it's disabled.

So how do we get a component to react to an attribute changing?

Let's go back to the example above where we take an attribute and simply put the attribute value in as text in our component. The first requirement is to "register" your attribute with a static property observedAttributes. Once you have the attribute registered, you can add a method attributeChangedCallback() to your component class, and that will be called every time an attribute changes.

Now, I'm going to move my template rendering into its own method render(). This makes it much easier to re-render the template when an attribute changes. I'm also doing a check to see if the name of the changed attribute is "my-attr". This isn't strictly necessary, but it's showing what you get in this method when attributes do change.

One thing we're doing is also checking if the shadow root has been added yet. There are cases where attributes are parsed and the attributeChangedCallback is called even before connectedCallback is called. So, we just early exit if that's the case!

Go ahead, give it a try below! Inspect our element, change the attribute, and you should see it update its dom and change!

That was a lot of work!

Yeah, admittedly, that is a lot of work. Web components give us the primitives to do this sort of thing, but wouldn't it be nice to just treat these things like a framework component? Meaning, is there a a way we can just update data and let the template update like in React or Vue or Svelte? The answer's yes! In the next post I'll be introducing Lit and things will get a lot easier!

⬅️ Previous Post Next Post ➡️
Back to top