Lit: what is public reactive properties
Tags: lit, google, webcomponents
Published: 2022-09-10 13:42:33

Lit components receive input and store a state.
Reactive properties are properties that can trigger the reactive update cycle when changed, re-rendering the component, and can optionally be read or written to attributes.

 
Lit manages:

- **Reactive Updates**: Lit generates a getter / setter pair for each reactive property. When a reactive property changes, the component schedules an update.

- **Attribute management**: By default, Lit sets an observed attribute corresponding to the property and updates the property when the attribute changes. Property values can also, optionally, be reflected in the attribute.

- **Superclass Property**: Lit automatically applies property options declared by a superclass. You don't need to declare the properties again unless you want to change the options.

- **Element update**: If a Lit component is defined after the element is already in the DOM, Lit manages the update logic, ensuring that any property set on an element before it was updated triggers the correct reactive side effects when the element is updated.

Public properties are part of the component's public API. In particular, public reactive properties should be treated as inputs.

The component should not change its public properties, except in response to user input.

Lit also supports internal reactive state, which refers to reactive properties that are not part of the component API. 

These properties do not have a corresponding attribute and are typically marked as secure or private in TypeScript.

The component is capable of manipulating its own internal reactive state.

In some cases, the internal reactive state can be initialized from public properties, for example if there is an expensive transformation between the user-visible property and the internal state.

As with public reactive properties, updating the internal reactive state triggers an update cycle.

Public reactive properties are declared using the @property decorator, possibly with a set of options.

Alternatively you can use a static property.

Class fields have a problematic interaction with reactive properties, because they are defined in the element instance.

Reactive properties are defined as ancillary on the element prototype.

According to the rules of JavaScript, an instance property takes precedence and effectively hides a prototype property.

This means that reactive property accessors don't work when class fields are used.

When a property is set, the element is not updated.

In JavaScript, it is not necessary to use class fields when declaring reactive properties. Instead, the properties must be initialized in the element constructor.

In TypeScript, you can use class fields to declare responsive properties as long as you use one of these templates:

- With setting useDefineForClassFields in tsconfig to false.

- By adding the declare keyword to the field and entering
the initializer of the field in the constructor.

When compiling JavaScript with Babel, you can use class fields to declare reactive properties as long as you set setPublicClassFields to true in your babelrc's assumptions configuration.

The options object can have the following properties:

- **attribute**: Whether the property is associated with an attribute or a custom name for the associated attribute. Default: true. If the attribute is false, the converter, reflect, and type options are ignored.

- **converter**: custom converter for converting between properties and attributes. If not specified, use the default attribute converter.

- **hasChanged**: Function called whenever the property is set to determine if it has been changed and should trigger an update. If not specified, LitElement uses a strict inequality check (newValue! == oldValue) to determine if the property value has changed.

- **noAccessor**: Set to true to avoid generating default property accessors. This option is rarely needed. Default: false.

- **reflect**: if the property value is reflected in the associated attribute. Default: false.

- **state**: to be set to true to declare the property as an internal responsive state. The internal reactive state triggers updates like public reactive properties, but Lit doesn't generate an attribute for it and users don't have to access it from outside the component. Equivalent to using the @state decorator. Default: false.

- **type**: When converting a string-valued attribute to a property, Lit's default attribute converter will parse the string into the specified type and vice versa when reflecting a property into an attribute. If the converter is set, this field is passed to the converter. If the type is not specified, the default converter treats it as a type: String. When using TypeScript, it should generally match the TypeScript type declared for the field. However, the type option is used by the Lit runtime for string serialization / deserialization and should not be confused with a type checking mechanism.

Omitting the options object or specifying an empty options object is the same as specifying the default value for all options.

If you want to read this content in italian, [here](https://www.slideshare.net/EleonoraRocchi1/lit3pdf).