Where should you store state and how should it be managed in a ClojureScript application? Take the following code for example - it's a "game" where you travel either down or left.

(ns cljsfiddle)

; initialise the state
(set! (.-x js/window) 0)    
(set! (.-y js/window) 0)

; state modifiers
(defn inc-x! [value] (set! (.-x js/window) (inc (.-x js/window))))    
(defn inc-y! [value] (set! (.-y js/window) (inc (.-y js/window))))

(.addEventListener js/window "keyup" 
    (fn [event]
      (let [key-code (.-which event)]
        (= key-code 49) (inc-x!)
        (= key-code 50) (inc-y!)))
      (print (.-x js/window) (.-y js/window))))

I'm transitioning to ClojureScript from JavaScript and I realize this is written in a fairly JavaScript-y way. In addition, any advice on how to rewrite this in a more Clojure-esque way is welcomed.


State management is a pretty complex topic currently in the cljs-sphere. Not because it is so hard to do, but because people are still trying to figure out what the simplest approach to it might be. And this causes some very interesting solutions.

However, as you are new I will start with the simplest and most accepted one. Use an atom.

;initialize state
(def xy-atom (atom {:x 0 :y 0}))

(defn inc-x! [i]
  (swap! xy-atom update-in [:x] + i))
(defn inc-y! [i]
  (swap! xy-atom update-in [:y] + i))

; or use a method to update any of the keys
(defn inc-any! [key i]
  (swap! xy-atom update-in [key] + i))

Your addEventListener function is ok, just change:

 (print (.-x js/window) (.-y js/window))


(print (:x @xy-atom) (:y @xy-atom)) ;or
(print @xy-atom)

If you're curious about more sophisticated approaches to handling state in cljs look here:

Both of them are very interesting, just from the concept point of view. However, to get started, take it slow and play around with the atom thing.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.