Plain JS React Components in your Om app

Let's say you want to use an external library such as selectize.js in your Om application. First you'll need to include this library - if you're not using advanced compilation then you don't need externs - but you probably will be eventually (don't worry about it right now if you're just learning and making toy apps), so generate them here or get externs for a few common libraries here or just make your own.

Selectize is based off of jQuery and doesn't come bundled as a React component, but you can find a React wrapper for it here. If there isn't a React wrapper for a component you would like to use, well, you'd have to write your own - perhaps just do it directly in ClojureScript. But that's not what this post is about.

Now to include the ReactSelectize React component within your Om app (on 0.8.0-rc1 which is based on React 0.12.2 - you'll have to modify this slightly for older React versions because createElement is new), let's add this react-utils.core module:

(ns react-util.core)

(defn build [component props]
  (let [React (.-React js/window)]
    (.createElement React component (clj->js props))))

And inside of our Om app we just have to require react-util.core and call the build function with our React component as the first argument and the component's props as the second argument:

(ns example.core
  (:require [om.core :as om]
            [om-tools.dom :as dom :include-macros true]
            [om-tools.core :refer-macros [defcomponent]]
            [react-util.core :as react]]))

(defcomponent my-component
  [app-state owner]
  (render [_]
   (react/build (.-ReactSelectize js/window)
                {:selectId "my-select-id" :onChange #(.log js/console %)})))

So easy! Thanks to David Nolen for pointing out the obvious solution - it just works.

dnolen: making sure that all this stuff works was/is priority #1