Life-cycle hooks
Life-cycle hooks give you access to the rendered DOM node. The special
“attribute” :replicant/on-render registers a life-cycle hook. It will be
called after the underlying DOM node is changed:
(defn render-map [{:keys [places]}]
[:div
{:replicant/on-mount
(fn [{:keys [replicant/node]}]
(mount-map node))
:replicant/on-render
(fn [{:keys [replicant/node]}]
(update-map-places node places))}])
The function is called with a single argument, which is a map of these keys:
:replicant/triggeralways has the value:replicant.trigger/life-cycle:replicant/life-cycleone of::replicant.life-cycle/mount(initial render):replicant.life-cycle/update(successive updates):replicant.life-cycle/unmount(node is being removed from the DOM)
:replicant/nodethe DOM node:replicant/remembera function to remember a value:replicant/memorya remembered value from a previous life-cycle hook:replicant/dispatchthe dispatch function registered withreplicant.dom/set-dispatch!
:replicant/on-render triggers on all updates and gives you enough information
to know what happened. If you just want to do something on mount and/or unmount,
you can use :replicant/on-mount and :replicant/on-unmount, which work
exactly like :replicant/on-render, except they only trigger on their
respective life-cycle events.
Life-cycle hooks are called after the DOM has been modified.
§ Memory
Life-cycle hooks are typically used to interface with third-party libraries,
such as a mapping library, a graphing library,
etc. When working with such libraries you may need to construct an object on
mount and keep a reference to it around for later updates. Replicant passes a
function :replicant/remember to all life-cycle hooks for this purpose. You can
call it with whatever value you want, and that value will be available as
:replicant/memory in the next life-cycle hook.
The JavaScript interop tutorial demonstrates one way to use this feature.
:replicant/remember will associate your value with the DOM node in a
WeakMap.
§ Hooks as data
Life-cycle hooks can also be expressed with data and handled via
replicant.dom/set-dispatch!:
(require '[replicant.dom :as r])
(r/set-dispatch!
(fn [e hook-data]
(when (= :replicant.trigger/life-cycle
(:replicant/trigger e))
(println "Life-cycle hook triggered!")
(println "Life-cycle" (:replicant/life-cycle e))
(println "Node:" (:replicant/node e))
(println "Hook data:" hook-data))))
(defn render-map [{:keys [places]}]
[:div
{:replicant/on-render
[::update-map-places places]}])
For more details on this mechanism, refer to the event handler
guide which describes it in detail. It works exactly
the same for DOM and life-cycle events. You can use :replicant/trigger to
distinguish them.
Note that the global dispatch will only be called for life-cycle events when you
explicitly set a non-function value to one of :replicant/on-render,
:replicant/on-mount or :replicant/on-unmount on a node. You cannot use this
mechanism to react to any change in the DOM.