Javascript Interop pattern: reagent + fun(ElementById)

A common Javascript pattern in libraries is code as follows:

    <script id="code">
    // ...
const element = document.getElementById('chart');
// ...
const timeline = new TimelineChart(element, data, { // ... 

The key part being to grab an element and feed that element to a function. In Reagent (React), however, this pattern is more difficult for me to adapt because of the different sequencing and the virtual dom.

For this kind of interop is creating a form-3 component the best way of implementing this, or is there a simpler way of utilizing this pattern of library, or is the form-3 the way to go?

Something I do sometimes is to use React‘s ref prop with a function value on standard HTML elements:

(defn timeline-chart []
  [:div {:ref #(...)}
    ...])

This will be called with the current DOM node (whenever it changes,
so watch out for nil and updates).

3 Likes

Wow! I had no idea about :ref. What documentation should I have been reading to notice that?

Thanks!

First, take a look through https://reactjs.org/docs/refs-and-the-dom.html as it’s really a React feature, not reagent.

Then for how to use it in reagent, I found https://github.com/reagent-project/reagent/blob/master/doc/FAQ/UsingRefs.md and https://gist.github.com/pesterhazy/4d9df2edc303e5706d547aeabe0e17e1 to be enough to understand how to make it work.

3 Likes

Beautiful! Especially the Mysteries of Reagent series, which is new to me