Data-binding with Reagent/React and Google Closure

I want to use Closure because it is included out-of-the-box with ClojureScript. The trouble is, Closure does not seem to be readily compliant with the React concept of a Virtual DOM, and so typically works by decorating/creating non-virtual DOM items itself. This is causing me grief with data binding. I am trying to use goog autocomplete with data received by ajax api call. After the API call the data is put into my front-end database (I’m using reframe), and I need the goog autocomplete to use that data once it comes in. Whenever Figwheel reloads after initial rendering the AC works; but clearly this isn’t an option for production deployment.

I’ve tried making the item into a form-3 Reagent component, but still the item isn’t properly sensitive to the subscribed data updates. Has anyone figured this out before? Here is what I have now (which works after figwheel reload, but not just after data subscription reload)

(defn dummy-ac
  "Trying to make this more reagent compatible by creating the thing ourself.

  Consulting https://github.com/google/closure-library/blob/34fcddbda216bb338b2e631b988eb52ed4fdf025/closure/goog/ui/ac/ac.js#L31"
  []
  (let [display-key :state-name
	data (->> @(rfc/subscribe [:get-us-states]) (map display-key) (apply array))
	matcher (goog.ui.ac.ArrayMatcher. data)
	renderer (goog.ui.ac.Renderer.)
	input-handler (goog.ui.ac.InputHandler. nil nil nil)
	auto-complete (goog.ui.ac.AutoComplete. matcher renderer input-handler)
	_attach-ac (.attachAutoComplete input-handler auto-complete)]

    (r/create-class
     {:display-name "dummy-ac"
      :reagent-render
      (fn []
	[:input {:id "DUMMY" :default-value "Dummy States"}])
      :component-did-mount (fn [this]
			     (js/console.log "Mounted this:" (dom/dom-node this))
			     (.attachInputs input-handler (dom/dom-node this)))})))

I can’t give you the full example of how to do that, but the things you are looking for are probably easiest expressed using react hooks. In particular you want useEffect and useRef. The basic setup looks something like that, just replace any pdfjs reference with the closure autocomplete.

If you want to update the autocomplete suggestions, you’ll likely need another useRef to keep the reference to the autocomplete component, and then another useEffect to set the new values.

All in all I would strongly suggest using a react autocomplete. The closure UI stuff doesn’t really fit into the react model, and I doubt many people outside of google use it.

1 Like

I like your suggestion; it seems that Google Closure is not paradigmatically compatible with React, and may not be worth the trouble to implement. I’m looking at GitHub - reactjs/react-autocomplete: WAI-ARIA compliant React autocomplete (combobox) component or possible the Material UI thing at GitHub - reactjs/react-autocomplete: WAI-ARIA compliant React autocomplete (combobox) component. The MUI one is pretty, but I don’t know about bringing the whole MU ecosystem in.

Ugh. Forget about the react ecosystem;it seems hopelessly intertwined with npm. I tried to install react-select and, 3300 dependencies later, the download failed because of a circular dependency.

At least Closure is clean as a project.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.