Render
arguments:
fn(host: Element): Function
- callback function withhost
argument; returned function hashost
andtarget
argumentsoptions: Object
- an object, which has a following structure:{ shadowRoot: true }
(default value) - initializes Shadow DOM and settarget
asshadowRoot
{ shadowRoot: false }
- setstarget
argument ashost
,{ shadowRoot: { extraOption: true, ... } }
- initializes Shadow DOM with passed options forattachShadow()
method
returns:
hybrid property descriptor, which resolves to a function (when called manually, it returns
target
)
Render factory creates and updates the DOM structure of your custom element. It works out of the box with built-in template engine, but the passed fn
function may use any external UI library that renders DOM.
Click and play with render factory example using React library:
Render factory trigger the update of the DOM by the observe
method of the descriptor. It means that an update is scheduled with the internal queue and executed in the next animation frame. The passed fn
is always called for the first time and when related properties change.
If you use render factory for wrapping other UI libraries, remember to access required properties from the host
synchronously in the body of fn
function (only then cache mechanism can save dependencies for the update). Otherwise, your function might be called only once.
Click and play with render factory using lit-html library:
Translation
The render
key of the property is not mandatory. The first rule of the translation allows setting fn
function as a render
property directly, and use the render factory implicitly:
Shadow DOM
The factory by default uses Shadow DOM as a target
, which is initialized when the component is rendered for the first time. Usually, you can omit options
object and use translation rule for the render factory (described above).
Although, If your element does not require style encapsulation and children distribution (<slot>
element can be used only inside of the shadowRoot
) you can disable Shadow DOM in the options
object. Then, target
argument of the update function becomes a host
. As a result, your template will replace children's content of the custom element.
Keep in mind that the options
can be passed only with render(fn, options)
factory function called explicitly:
Manual Update
You can trigger an update process by calling property manually from the element instance:
The render
factory uses the same cache mechanism like other properties. The update process calls fn
only if related properties have changed. However, calling myElement.render()
manually always invokes the result of the fn()
(it always triggers update process).
Reference Internals
If your element should expose internal parts of the content as a public API, you can use render
property to define an internal DOM element from the rendered content as another property. Using render
in the getter of the defined property ensures that render process is called and it adds it to the dependencies of the property. The result of the call gives us a target
element, so you don't have to relay on the render configuration (it might be the shadowRoot
as well as the host
element - but both has querySelector
API):
The canvas
property from the above example will always reference the proper element from the shadowRoot. Even though the render process is asynchronous, if the user gets canvas
before the first scheduled render, it will return the element interface because of calling render()
manually. Moreover, the cache mechanism ensures that the canvas
property result is cached. It is recalculated only when dependencies of the render property change. This allows creating dynamic selectors, which returns different results depends on the render dependencies.
If you have more references to internal elements, you can create simple factory and use it multiple times:
Unit Testing
Because of the asynchronous update mechanism, it might be tricky to test if the custom element instance renders correctly. However, you can create your unit tests based on the definition itself.
The render key is usually a function, which returns the update function. It can be called synchronously with mocked host and arbitrary target element (for example <div>
element):
If you use render
factory explicitly, your template definition can be defined outside of the factory call:
Last updated
Was this helpful?