Skip to content

Instantly share code, notes, and snippets.

@joelash
Forked from manicolosi/reagent-lifecycle-async.cljs
Last active November 3, 2015 18:04
Show Gist options
  • Save joelash/86aa8239bd57e229c78e to your computer and use it in GitHub Desktop.
Save joelash/86aa8239bd57e229c78e to your computer and use it in GitHub Desktop.
;; Async Lifecycle
(defn lifecycle-channel [component]
(let [tap-ch (async/chan)]
(-> (.-lifecycleChannel component)
:mult
(async/tap tap-ch))
tap-ch))
(defn with-lifecycle [klass]
(let [ch (async/chan)
mult (async/mult ch)
tap-ch (async/chan)
handle (fn [event & extra-args]
(fn [& args]
(async/put! ch event)
(when-let [f (event klass)]
(apply f (concat extra-args args)))))]
(async/tap mult tap-ch)
(into
{:component-will-mount
(fn [this]
(set! (.-lifecycleChannel this) {:ch ch :mult mult})
((handle :component-will-mount) this))
:component-will-unmount
(fn [this]
((handle :component-will-unmount) this)
(async/untap-all mult)
(async/close! ch))
:reagent-render
(fn [& args]
(async/put! ch :reagent-render)
(when-let [f (or (:reagent-render-with-lifecycle klass)
(:reagent-render klass))]
(apply f (cond->> args
(:reagent-render-with-lifecycle klass)
(cons tap-ch)))))}
(for [event [:get-initial-state :component-will-receive-props
:should-component-update :component-did-mount
:component-will-update :component-did-update]]
[event (handle event)]))))
@manicolosi
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment