Refs

The ref attribute can be used to export an element so that a component can gain access to it. It is recommended that the ref attribute is filtered via the attrsfilter so that it is not exposed to the HTML.

Using refs in a template

<button {{ { ref: arrow } | attrs }} type="button" class="btn--reset">
    <span class="icon-ic svg-arrow"><svg>...</svg></span>
    <span class="visuallyhidden">{{ title }}</span>
</button>

Connecting to refs from JavaScript

And within the JavaScript code, it can be accessed with High-Order Component withRefs:

import { withRefs } from 'melody-hoc';
const enhance = withRefs(component => ({
    arrow: element => {
        component.clickHandler = (event) => {
            event.stopPropagation();
            const { itemId, direction } = component.getState();
            component.props.callToAction();
        };
        element.addEventListener('click', component.clickHandler);
        return {
            unsubscribe() {
                element.removeEventListener('click', component.clickHandler);
                component.clickHandler = null;
            }
        }
    }
}));

The above defines a ref handler with the name arrow which is exposed to the template. A ref handler receives the element instance and is expected to return a subscription object.

Understanding ref handlers

Any function of the form (element) => ({ unsubscribe() { /* logic to release the element again */ } }) is called a ref handler. The signature might seem weird at first, however, it allows for a very nice integration with Rx.js.

const myButtonRefHandler = element => fromEvent('click', element).pipe(
    tap(event => console.log('clicked'))
).subscribe(() => alert('You clicked the button!'));

Last updated

Was this helpful?