Skip to content

Latest commit

 

History

History
42 lines (31 loc) · 1.82 KB

state.md

File metadata and controls

42 lines (31 loc) · 1.82 KB

State

UIx is using React's state hook for local state.

(defui form []
  (let [[value set-value!] (uix.core/use-state "")]
    ($ :input {:value value
               :on-change #(set-value! value (.. % -target -value))})))

In some React wrappers state is represented using the Atom datatype that has has reset! and swap! operations. We take a similar naming approach and suffix state updating function with a bang ! denoting that the operation is mutating a value.

Similar to clojure.core/swap!, set-value! from the above example also takes a function that will receive the current value and arbitrary number of additional arguments, and return the next value of component's state.

When the initial value has to be computed before it’s used, it is recommended to pass it in a callback to use-state. The callback will be executed only once, in component’s initialization stage.

(defn calculate-initial-value []
  ;; expensive computation here
  )

(uix.core/use-state calculate-initial-value)

Reusable state

Because state is not directly coupled with components it is possible to build reusable behaviors on top of it. In the example below we create a use-validation function to encapsulate logic that keeps track of a value and applies updates when the value satisfies provided validation function.

(defn use-validation [initial-value valid?]
  (let [[value set-value!] (uix.core/use-state initial-value)
        on-change #(let [v (.. % -target -value)]
                    (when (valid? v)
                      (set-value! v)))]
    [value on-change]))

(defui form []
  (let [[value on-change] (use-validation "" #(not (empty? %)))]
    ($ :input {:value value
               :on-change on-change})))