A hopefully short and concise explanation as to how Om/React.js works. This probably isn't for you if you already use ClojureScript or Om.
The front end and JavaScript God known as David Nolen created a ClojureScript library called Om. Om is a front end library that uses React.js and makes web MVC not just obsolete, but an anti-pattern.
In Om there's just the data and the view.
-
data =>
-
is different or unset? =>
-
if true, render dom.
Parts of the view is updated only when the data changes.
-
original-state = array("name1", "name2") =>
-
event triggered =>
-
new-state = array("name1", "name2", "name3") =>
-
is different or unset? =>
-
if true, render dom
If not MVC, what is it? It's parent-data.
Let's say you have an application for managing cars. This might be the initial state of your application.
(defonce app-sate
(atom {:cars
[{:id 1 :car "old red" :slot 10}
{:id 80 :car "new blue" :slot 40}]}))
Let's say you have a view called parking-space. (using om tools)
;; car - value from the car keyword in the app state
(defcomponent parking-space [car owner]
(render
[_]
(let [{:keys [car id]} car]
;; <li>...</li>
(dom/li
;; tag attributes
{:class "parking space"
:id (str "parking-space-" (gensym))}
;; <h2>..</h2>
(dom/h2 car)
;; <a id="" href="" onClick="">remove</a>
(let [html-id (str "example-" id)
href (str "#" html-id)
remove (fn [& _]
(swap! app-state
update-in
[:cars]
(fn [cars]
(remove #(-> % :id (= id)) cars))))]
(dom/a {:id html-id
:href href
:on-click remove} "remove"))))))
Now let's say you have a parking lot. (using om tools)
;; app - application state
(defcomponent parking-lot [app owner]
(render
[_]
;; <ul>..</ul> - unordered list
(dom/ul
;; tag attributes
{:class "parking lot"
:id "parking-lot"}
;; array_map(parkingSpace, carsArray);
(om/build-all parking-space (:cars app)))))
Where should this parking lot go?
;; set React.js parking-lot function
(defn main []
(om/root
(fn [app owner]
(parking-lot app owner))
app-state
{:target (. js/document
(getElementById "parking-lot"))}))
All you have to do now is modify the data and the view takes care of the rest
That's literally it. You can think of it this way =>
-
Create bindings
-
Add/Remove/Update data
-
Relax.