Why can you set a lit public property 'attribute' option to false?

Viewed 225

From the Lit documentation: "The component shouldn't change its own public properties, except in response to user input."

Also from the documentation: "Internal reactive state works just like public reactive properties, except that there is no attribute associated with the property."

However, when you declare a property, there is an option of setting attribute to false, which prevents an attribute from being associated with the property.

@property({attribute: false})
data = {};

What would be the purpose of doing this? Wouldn't the property just act like internal state at that point?

For reference, Lit already has several ways of declaring internal state variables, either with the @state decorator or setting the state option to true, so I'm just not sure why they allow this too.

2 Answers

This way you are really free to use any combination.

  • A property which acts also as state and attribute
  • A property which acts also as state but not as an attribute
  • A state, which is not a property
  • A property, which is an attribute
  • A property which is not an attribute

see also https://javascript.info/dom-attributes-and-properties for the difference between properties and attributes.

I think the main use case for this is for when you have to pass big complex data to the component but want it to be set directly as a property and still get lit to rerender stuff for you.

I think this is easier to visualize with an example, let's say you're making a component which will render a list out of an array passed as a property.

If the array was set as an attribute, it would look something like this:

<list-renderer items='[{id: "1", name: "John Doe"}, {id: "2", name: "Alice Williams"}]'></list-renderer>

Now, this example only has two items, but it could be something way bigger, and that attribute will eventually need to be serialized into an array using JSON.parse() by lit. So, you're just doing an extra step, especially if you already had the array as a JS object rather than JSON data.

So, for this kind of cases it's easier to just force users to set items as a JS property directly.

This will also apply for when you need to pass complex configuration setting objects or functions to the component.

Then again, for most of the components you'll be making, you will probably stick with either having the attribute or making it a fully internal state property.

Related