-
-
Save miguelbermudez/a5703c362316c7b19d58b168d82167df to your computer and use it in GitHub Desktop.
Redux with basically no effort in clojurescript, plus core.async to handle asynchronous actions
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 reduxish.state-tools | |
(:require-macros [cljs.core.async.macros :refer [go go-loop]]) | |
(:require [cljs.core.async.impl.protocols :refer [WritePort ReadPort]] | |
[cljs.core.async :refer [<!]])) | |
(defn channel? | |
"A predicate that determines if the provided thing is a core.async channel" | |
[ch] | |
(and (satisfies? WritePort ch) (satisfies? ReadPort ch))) | |
(defn dispatch! | |
"Dispatch an action. Not to be used on its own" | |
[reducer state value] | |
(if (channel? value) | |
(go (loop [] | |
(when-let [message (<! value)] | |
(<! (dispatch! state reducer message)) | |
(recur)))) | |
(go (prn state reducer value) (swap! state reducer value)))) | |
(defn action | |
"Flux-standard-action action creator fn" | |
([type] { :type type}) | |
([type payload] { :type type :payload payload})) | |
(defn dispatch-on-type | |
"Use this to make reducers quickly!" | |
[_ {:keys [type]}] type) | |
(defn make-store | |
"Creates a new redux-ish store" | |
[reducer] | |
(let [state (atom (reducer))] | |
{:state state | |
:dispatch! (partial dispatch! reducer state)})) | |
;; Create a reducer that increments or decrements a value | |
(defmulti reducer dispatch-on-type) | |
(defmethod reducer :default [] 0) | |
(defmethod reducer :increment [state action] (inc state)) | |
(defmethod reducer :decrement [state action] (dec state)) | |
(let [{:keys [dispatch! state]} (make-store reducer)] | |
(go | |
(<! (dispatch! (action :increment))) | |
(<! (dispatch! (action :increment))) | |
(println @state))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment