diff --git a/src/quiescent/core.cljs b/src/quiescent/core.cljs index 7061846..7ca2082 100644 --- a/src/quiescent/core.cljs +++ b/src/quiescent/core.cljs @@ -56,6 +56,11 @@ [method (impl-ctor impl)])))) opts-map))) +(deftype ValueWithKey [value react-key]) + +(defn with-key [value react-key] + (ValueWithKey. value react-key)) + (defn component "Return a factory function that will create a ReactElement, using the provided function as the 'render' method for a ReactJS component, which is created and instantiated behind-the-scenes. @@ -72,6 +77,11 @@ :keyfn - a single-argument function which is invoked at component construction time. It is passed the component's value, and returns the ReactJS key used to uniquely identify this component among its children. + The key may also be set by applying a key to the value at call time using the with-key + function, e.g. (MyComponent (with-key value key) ...), which will override :keyfn. + This has the advantage that neither every component that may be part of a sequence has to + implement a :keyfn function nor does the component have to know that fact and how to generate + a key which will not be needed by the component for any other purpose. :name - the name of the element, used for debugging purposes. @@ -135,11 +145,13 @@ (build-lifecycle-impls opts)) react-component (.createClass js/React (clj->js impl))] (fn [value & constant-args] - (let [props (js-obj)] - (set! (.-value props) value) + (let [props (js-obj) + [real-value react-key] (if (instance? ValueWithKey value) + [(.-value value) (.-react-key value)] + [value (when-let [keyfn (:keyfn opts)] (keyfn value))])] + (set! (.-value props) real-value) (set! (.-constants props) constant-args) - (when-let [keyfn (:keyfn opts)] - (set! (.-key props) (keyfn value))) + (when react-key (set! (.-key props) react-key)) (.createElement js/React react-component props)))))) (defn unmount