Hello everyone!
I implemented a slider component in Reagent + D3 using reagent/create-class:
(ns slider
(:require [reagent.core :as reagent]
[reagent.impl.util :as util]))
(defn slider [{:keys [name width height value on-change]}]
(let [w (or width 150)
h (or height 20)]
(reagent/create-class {
:component-did-mount
(fn [this]
(let [pos->value #(-> js/d3 (.mouse (.getDOMNode this)) first (/ w)
(min 1) (max 0))
on-drag #(on-change (pos->value))
drag (-> js/d3 .-behavior .drag
(.on "drag" on-drag))]
(-> js/d3
(.select (.getDOMNode this))
(.call drag))))
:render (fn [this]
(let [value (-> this util/get-props :value)]
[:svg {:width w :height h}
[:g {:className "slider"}
[:rect {:className "slider__rect" :x 1 :y 1 :width (- w 3)
:height (- h 3) }]
[:rect {:className "slider__fill__rect"
:x 2 :y 2
:width (- (* w value) 4) :height (- h 4) }]
[:text {:className "slider__text" :x (/ w 2) :y (/ h 2)}
name]]]))})))
Here the properties of the component are specified in the outer "slider"
function. The values of these function params, however, are not getting updated
when accessed from the inner render function on subsequent calls, of course. So
the value of the parameter "value" always stays the same as when the component
was first created, even if the actual property has changed. This is ugly and
was a source of confusion for me.
I could resort to calling reagent.impl.util/get-props to get the most current
property values in "render", and it works. However, get-props seems to be an
internal function, so it is probably not intended to be called directly.
When using the alternative way of constructing components with "with-meta", the
properties are passed as parameters directly to the render function. Hence,
render always sees the most current values:
(def slider
(with-meta
(fn [{:keys [name width height value on-change]}] ...)
{:component-did-mount
(fn [this] ...)}))
This way there is at least less confusion, because there are no variables with
obsolete property values here. But component-did-mount does not get the
properties directly and has to use get-props again.
Personally, I would prefer using create-class for components with extra
life-cycle functions, but this confusion with the variables getting obsolete
makes it much less attractive than it could be.
Am I missing something obvious? What is the proper way of defining component
properties which allows all the life-cycle functions to see them?
Thanks in advance!
Ilya
--
Note that posts from new members are moderated - please be patient with your
first post.
---
You received this message because you are subscribed to the Google Groups
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/clojurescript.