Skip to content

Instantly share code, notes, and snippets.

@swannodette
Last active September 15, 2016 08:48
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swannodette/7915826 to your computer and use it in GitHub Desktop.
Save swannodette/7915826 to your computer and use it in GitHub Desktop.
(ns react-cljs.core
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [om.core :as om]
[om.dom :as dom :include-macros true]
[cljs.core.async :refer [>! <! chan put! sliding-buffer]]))
(enable-console-print!)
(def app-state
(atom {:counters (into [] (map (fn [n] {:id n :count 0}) (range 10)))}))
(defn counter [data chans]
(dom/component
(dom/div nil
(dom/label nil (:count data))
(dom/button
#js {:onClick
(fn [e]
(do
(om/update! data [:count] inc)
(put! (:last-clicked chans)
(-> data meta :om.core/path))))}
"+")
(dom/button
#js {:onClick (fn [e] (om/update! data [:count] dec))}
"-"))))
(defn counters []
(let [last-clicked (chan (sliding-buffer 1))
chans {:last-clicked last-clicked}]
(om/root
app-state
(fn [data]
(reify
dom/IWillMount
(-will-mount [_ _]
(go (while true
(om/replace! data [:message] (<! last-clicked)))))
dom/IRender
(-render [_ _]
(dom/div nil
(into-array
(concat
[(dom/h1 #js {:key "head"} "A Counting Widget!")
(dom/div #js {:style
(if (:message data)
#js {:display "block"}
#js {:display "none"})}
(when-let [lc (:message data)]
(str "Last clicked item was " (last lc))))]
(map #(om/render counter data
{:path [:counters %] :opts chans :key :id})
(range (count (:counters data))))))))))
js/document.body)))
(counters)
(defproject react-cljs "0.1.0-SNAPSHOT"
:description "FIXME: write this!"
:url "http://example.com/FIXME"
:dependencies [[org.clojure/clojure "1.5.1"]
[org.clojure/clojurescript "0.0-2122"]
[org.clojure/core.async "0.1.267.0-0d7780-alpha"]
[om "0.1.0"]]
:plugins [[lein-cljsbuild "1.0.0"]]
:source-paths ["src"]
:cljsbuild {
:builds [{:id "dev"
:source-paths ["src"]
:compiler {
:output-to "main.js"
:output-dir "out"
:optimizations :none
:source-map true
:foreign-libs [{:file "om/react.js"
:provides ["React"]}]
:externs ["om/externs/react.js"]}}]})
@swannodette
Copy link
Author

path is so that components can update their own state in the tree, it gives us the power of setState without actually needing setState. It's no longer an explicit parameter, it's metadata on the data received by a component. Yes data is like state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment