Skip to content

Instantly share code, notes, and snippets.

@chpill
Last active May 2, 2017 21:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chpill/cb9a9f8d94b7ca30ea2078deaa037f5b to your computer and use it in GitHub Desktop.
Save chpill/cb9a9f8d94b7ca30ea2078deaa037f5b to your computer and use it in GitHub Desktop.
Pseudo redux with rum bindings in clojurescript
(ns remux.core)
(defn create-store [handlers initial-state]
(let [state (atom initial-state)
dispatching? (atom false)]
{::state state
::get-state (fn get-state [] @state)
::get-raw-state #(state)
::dispatch
(fn [action-name data]
(when dispatching?
(throw (ex-info "Do not dispatch in an action handler!" {})))
(when-let [handler (get handlers action-name)]
(try
(reset! dispatching? true)
(swap! state handler data)
(finally
(reset! dispatching? false)))))}))
(ns remux.rum
#?(:cljs (:require [goog.object :as gobj]
[goog.async.nextTick])))
(let [dispatch-k "remux/dispatch"
context-types #?(:cljs {dispatch-k js/React.PropTypes.func}
:clj {})]
(defn add-dispatch-to-context
"Add to current react context a dispatch fn. The store that contains the
dispatch fn must be provided as argument to the component to which this mixins
is applied. The `get-store-fn` will then be used to extract the store from the
arguments."
[get-store-fn]
#?(:cljs
{:init (fn [s props]
(assoc s ::store {get-store-fn props}))
:class-properties {:childContextTypes context-types}
:child-context (fn [s]
(let [{:keys [dispatch]} (::store s)]
{dispatch-k dispatch}))}))
(def with-dispatch
#?(:cljs
{:class-properties {:contextTypes context-types}
:will-mount (fn [s]
(let [dispatch (-> (:rum/react-component s)
(gobj/get "context")
(gobj/get dispatch-k))]
(assoc s ::dispatch dispatch)))
:will-unmount (fn [s] (dissoc s ::dispatch))})))
(defn dispatch [s action]
#?(:cljs ((::dispatch s) action)))
(defn dispatch-async [s action]
#?(:cljs (goog.async.nextTick ((::dispatch-sync s) action))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment