# Refs

{% hint style="warning" %}
Refs are a low-level API that have not been revisited to support `melody-hooks`. They are incredibly useful when using `melody-component` and `melody-hoc`, especially when combined with [Rx.js](https://rxjs-dev.firebaseapp.com/) but at the moment we have not decided on how to use them with `melody-hooks`.
{% endhint %}

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 `attrs`filter so that it is not exposed to the HTML.

## Using refs in a template

```javascript
<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`:

```javascript
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](https://rxjs-dev.firebaseapp.com/).

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

