Last active
February 1, 2017 01:59
-
-
Save waterlink/629ce057cd2aded7a206 to your computer and use it in GitHub Desktop.
Reagent with Redux?
This file contains hidden or 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
;; My idea of hierarchical Redux | |
;; ------------ | |
;; reducers | |
;; reducers for todos (todo list) | |
(defmulti todos-reducer (fn [state ty data] ty)) | |
(defmethod todos-reducer :todo-add [state ty {:keys [title done]}] | |
(let [state (update-in state [:counter] inc) | |
id (:counter state) | |
todo (new-todo-state id title done) ;; this is (atom {.. todo .. + todo reducers}) | |
state (append-child-state state todo)] | |
(assoc-in state [:todos id] todo))) | |
(defmethod todos-reducer :todo-del [state ty {:keys [id]}] | |
(let [todo (get-in state [:todos id]) | |
state (remove-child-state state todo)] | |
(dissoc-in state [:todos id]))) | |
;; .. and so on .. | |
(defmethod todos-reducer :default [state ty data] state) | |
;; reducers for single todo list | |
(defmulti todo-reducer (fn [state ty {:keys [id]}] | |
(if (-> (:id state) (= id)) | |
ty | |
:default))) | |
(defmethod todo-reducer :todo-toggle [state ty data] | |
(update state :done not)) | |
(defmethod todo-reducer :todo-update [state ty {:keys [title]}] | |
(assoc state :title title)) | |
;; .. and so on .. | |
(defmethod todo-reducer :default [state ty data] state) | |
;; ------------ | |
;; state | |
(defonce state-reducers [todos-reducer]) | |
(defonce state-todo-reducers [todo-reducer]) | |
(defonce state (atom {:counter 0 | |
:todos (sorted-map) | |
:redux-reducers state-reducers | |
:redux-children (sorted-map)})) | |
(defn new-todo-state [id title done] | |
"creates new todo state with data and special :redux-* keys for houskeeping" | |
(atom {:id id :title title :done done | |
:redux-reducers state-todo-reducers | |
:redux-children (sorted-map)})) | |
(defn append-child-state [state child] | |
"appends new child state" | |
(assoc-in state [:redux-children (:id child)] child)) | |
(defn remove-child-state [state child] | |
"removes existing child state" | |
(dissoc-in state [:redux-children (:id child)] child)) | |
(defn redux [state ty data] | |
"applies state's own reducers to it using action [ty data]" | |
(let [reducers (:redux-reducers state)] | |
(reduce #(%2 %1 ty data) state reducers))) | |
(defn rec-redux [state ty data] | |
"applies redux to the state and to all of its children" | |
(do | |
(redux state ty data) | |
(when-let [children (:redux-children state)] | |
#(map #(dispatch-to! % ty data) (vals children))))) | |
(defn dispatch-to [state ty data] | |
(trampoline rec-redux state ty data)) | |
(defn dispatch-to! [state ty data] | |
"dispatches an action to a specific state" | |
(swap! state dispatch-to ty data)) | |
(defn dispatch! [ty data] | |
"dispatches an action to a root state" | |
(dispatch-to! state ty data)) |
This file contains hidden or 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
;; My current understanding of idiomatic Redux | |
;; ------------ | |
;; reducers | |
(defmulti reducer (fn [state ty data] ty)) | |
(defmethod reducer :add-todo [state ty {:keys [title done]}] | |
(let [state (update-in state [:counter] inc) | |
id (:counter state)] | |
(assoc-in state [:todos id] {:id id :title title :done done}))) | |
(defmethod reducer :toggle-todo [state ty {:keys [id]}] | |
(update-in state [:todos id :done] not)) | |
(defmethod reducer :update-todo [state ty {;keys [id title]}] | |
(assoc-in state [:todos id :title] title)) | |
;; .. and so on .. | |
(defmethod reducer :default [state ty data] state) | |
;; ------------ | |
;; state | |
(defonce state (atom {:counter 0 | |
:todos (sorted-map)})) | |
(defonce state-reducers [reducer]) | |
(defn redux [state reducers ty data] | |
"redux is for calculating new state using action [ty data] from state by applying all reducers" | |
(reduce #(%2 %1 ty data) state reducers)) | |
(defn dispatch! [ty data] | |
"dispatch is for generating new action [ty data]" | |
(swap! state redux state-reducers ty data)) | |
; ------------- | |
; components | |
(defn home [] | |
;; yes, this is the only atom dereference | |
[:div [todolist (:todos @state)]]) | |
(defn todolist [todos] | |
[:ul | |
(for [id (keys todos)] | |
^{:key id} [todolistitem (get todos id)])]) | |
;; this one is irrelevant for the example | |
;; nor it and none of child components do not dereference any atoms at this point | |
(defn todolistitem [] ... ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment