Last active
February 3, 2016 10:54
-
-
Save jellea/257633d5ceb962cb3cac to your computer and use it in GitHub Desktop.
Minimal Redux implementation in clojurescript. Two versions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(def initial-state {:counter 0}) | |
(defonce !state (r/atom initial-state)) | |
(defonce !actions (atom [])) | |
(defprotocol Action | |
(reducer [action state])) | |
(defn dispatch! [action] | |
(swap! !actions conj action)) | |
;; Listen for new action and reduce into new-state | |
(add-watch !actions :reduce | |
(fn [_ _ _ new-state] | |
(let [new-action (last new-state)] | |
(swap! !state #(reducer new-action %))))) | |
;; Roll your own Action: | |
;; | |
;; (defrecord IncrementCounter [num]) | |
;; | |
;; (extend-protocol Action | |
;; IncrementCounter | |
;; (reducer [{:keys [num]} state] | |
;; (update state :counter #(+ % num)))) | |
;; | |
;; Dispatch Action: (dispatch! (->IncrementCounter 2)) | |
;; TODO: Selectors: http://rackt.org/redux/docs/recipes/ComputingDerivedData.html | |
;; Would reagents cursors or track do the trick? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(def initial-state {:counter 0}) | |
(defonce !state (r/atom initial-state)) | |
(defonce !actions (atom [])) | |
(defmulti Action (fn [action state] (:type action))) | |
(defn dispatch! [action] | |
(swap! !actions conj action)) | |
;; Listen for new action and reduce into new-state | |
(add-watch !actions :reduce | |
(fn [_ _ _ new-state] | |
(let [new-action (last new-state)] | |
(swap! !state #(Action new-action %))))) | |
(defn rereduce | |
"Reduce past actions over state to get a fresh copy. As all actions | |
are stored as data, changes in actions will be projected on state. | |
Useful for live reload." | |
[] | |
(reset! !state (reduce #(Action %2 %1) initial-state @!actions))) | |
;; Roll your own Action: | |
;; | |
;; (defmethod Action :Increment [{:keys [num]} state] | |
;; (update state :counter #(- % num))) | |
;; | |
;; | |
;; Dispatch Action: | |
;; | |
;; (dispatch! {:type :Increment :num 10}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns redux-test.reagent-example | |
(:require [reagent.core :as r])) | |
(enable-console-print!) | |
;; MODEL | |
(def initial-state {:counter 0 | |
:list []}) | |
(defonce !state (r/atom initial-state)) | |
(defonce !actions (r/atom [])) | |
(defn dispatch! [action] | |
(swap! !actions conj action)) | |
(defmulti Action (fn [action state] (:type action))) | |
(add-watch !actions :reduce | |
(fn [_ _ _ new-state] | |
(let [new-action (last new-state)] | |
(swap! !state #(Action new-action %))))) | |
(defn rereduce | |
"Reduce past actions over state to get a fresh copy. As all actions | |
are stored as data, changes in actions will be projected on state." | |
[] | |
(reset! !state (reduce #(Action %2 %1) initial-state @!actions))) | |
;; ACTIONS | |
(defmethod Action :Change [_ state] | |
(update state :list #(conj % "more"))) | |
(defmethod Action :Increment [{:keys [num]} state] | |
(update state :counter #(- % num))) | |
;; VIEW | |
(defn root [] | |
[:div | |
[:pre "state: " (str @!state)] | |
[:pre "actions: " (str @!actions)] | |
[:button {:on-click #(dispatch! {:type :Change})} "more"] | |
[:button {:on-click #(dispatch! {:type :Increment :num 10})} "+10"]]) | |
(r/render [root] (js/document.getElementById "app")) | |
(defn on-js-reload | |
"Hook for figwheel reload" | |
[] | |
(rereduce)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment