Re-frame
highlight.js 설치
yarn add highlight.js
lein new re-frame re-frame-example-10x +10x
;; We will alias re-frame.core to rf: (rf/dispatch [:buy 32343])
Events are vectors. They are named by a keyword in the first position. You can attach other data to the Event after the name. In the case above, the :buy Event needed an item id to know what the user wants to buy.
(defn buy-button [item-id]
[:button
{:on-click (fn [e]
(.preventDefault e)
(ajax/post (str "http://url.com/product/" item-id "/purchase")
{:on-success #(swap! app-state assoc :shopping-cart %)
:on-error #(swap! app-state update :errors conj)}))}
"Buy"])
That Component does quite a lot! It defines:
- How to calculate the products' purchase URL
- Where to store the item in the cart when a response comes back
- How to handle a request error
There is more code for handling these chores than for rendering HTML. Re-frame's Events help you separate out concerns. If your code is about rendering HTML, it goes in a Component. If it is about interpreting the user's intent or having effects outside of the component, it goes in an Event.
Using those guidelines, let's rewrite our Component:
(defn buy-button [item-id]
[:button
{:on-click (fn [e]
(.preventDefault e)
(rf/dispatch [:buy item-id]))}
"Buy"])
Here's how we can define how to handle the :buy event.
(rf/reg-event-fx ;; register an event handler
:buy ;; for events with this name
(fn [cofx [_ item-id]] ;; get the co-effects and destructure the event
{:http-xhrio {:uri (str "http://url.com/product/" item-id "/purchase")
:method :post
:timeout 10000
:response-format (ajax/json-response-format {:keywords? true})
:on-success [:added-cart]
:on-failure [:notified-error]}
:db (update-in (:db cofx) [:cart :items] conj {:item item-id})}))