Using Refs in Stencil

Gil Fink
2 min readAug 16, 2018

--

One of the main features of Stencil is the usage of JSX in order to implement the component render function. In React you can use refs to get hold on DOM elements that are part of your component. Stencil has the same ability, and you can use it when it is needed. In this post I’ll show you how to reference a DOM element which is a part of your Stencil component.

So, Let’s dive in.

Why to use Refs?

The first question that you might ask yourself is why to bother and use element references? Let’s clarify that.

In typical data flow you will pass props from the parent to it’s child elements. When passing props. the child component will re-render and you will get it’s new state shown on screen. There are times that you will need to imperatively modify a child outside of this typical flow. Here are some examples of things that might need different flow:

  • Triggering animation
  • Usage of third party components with their own API
  • Implementation of forms where you might need to do things such as text selection or focus.

Now that we understand that we might need references to inner elements, it’s time to understand how to implement them in Stencil.

Stencil Refs

In order to create a reference to an inner element in Stencil you will use the ref attribute. The ref attribute receives a function which accepts an element reference and returns void. In the function implementation you will set the reference to a parent component member.
Let’s see an example:

import {Component} from '@stencil/core';

@Component({
tag: 'custom-text-input',
shadow: true
})
export class CustomTextInput {
private textInput?: HTMLInputElement;

constructor() {
this.focusTextInput = this.focusTextInput.bind(this);
}

focusTextInput() {
this.textInput.focus();
}

render() {
return (
<div>
<input
type="text"
ref=
{el => this.textInput = el as HTMLInputElement} />

<input
type="button"
value="Focus the text input"
onClick=
{this.focusTextInput}
/>
</div>
);
}
}

In the example you can see that the CustomTextInput class has a private member called textInput. In the render function you set the reference to the input element using the following code:

ref={el => this.textInput = el as HTMLInputElement}

Then, when someone is clicking on the button, the focusTextInput is called and it will use the stored element to focus on the input element.

This is of course a simple example but I hope that you get the point of how to set a reference to an element.

Summary

Stencil components have the ability to reference child elements. You use the ref attribute and store the element reference for future usage. This ability can be very useful in specific scenarios such as triggering animation or running media. On the other hand, before using refs always try to figure first if you can achieve your goals with typical data flow using props.

--

--

Gil Fink

Hardcore web developer, @sparXys CEO, Google Web Technologies GDE, Pro SPA Development co-author, husband, dad and a geek.