Components

UIx components are normal ClojureScript functions that return Hiccup (DSL for HTML and React's Virtual DOM).

(defn button [{:keys [on-click]} child]
  [:button {:on-click on-click}
    child])
    
(defn text-input [{:keys [value type on-change]}]
  [:input {:value value
           :type type
           :on-change #(on-change (.. % -target -value))}])
           
(defn sing-in-form [{:keys [email password]}]
  [:form
    [text-input {:value email :type :email}]
    [text-input {:value password :type password}]
    [button {} "Sign in"]])

Even though components are declared as functions, they are still used in Hiccup form[component arg1 arg2 ...]

Attributes

Hiccup attributes are written as keywords in kebab-case. Values that are normally strings without whitespace can be written as keywords as well, this may also improve autocompletion in your IDE.

:key attribute

Unique keys are used in React to optimize rendering lists of items. In UIx :key attribute can be passed as normal attribute onto DOM elements such as :div

[:ul
  (for [n (range 100)]
    [:li {:key n} n])]

When rendering UIx components :key should be declared via metadata, unless you are passing useful data to a component.

[:ul
  (for [n (range 100)]
    ^{:key n} [list-item n])]

:ref attribute

Refs provide a way to refer to DOM nodes or React elements. In UIx ref is provided as Atom-like data type. Ref is passed as a normal attribute onto DOM elements.

(defn form []
  (let [ref (uix.core/ref)]
    [:form
      [:input {:ref ref}]
      [:button {:on-click #(.focus @ref)}
        "press to focus on input"]]))

UIx components doesn't take refs because they are built on top of React's function-based components that doesn't have instances.

When you need to pass a ref into child component, pass it as a normal value.

(defn text-input [{:keys [ref]}]
  [:input {:ref ref}])

(defn form []
  (let [ref (uix.core/ref)]
    [:form
      [text-input {:ref ref}]
      [:button {:on-click #(.focus @ref)}
        "press to focus on input"]]))

Last updated