DEV Community

Cover image for Reagent 101 / pt 3. / component
icncsx
icncsx

Posted on • Edited on

Reagent 101 / pt 3. / component

In Part 2 of the Reagent series, we talked about 3 types of components.

In this post, we will actually start to build components that use other components as building blocks. Let's start with this basic Form 1 component.

(defn greet-view []
  [:div.banner
    [:h1 "Hello, world"]])
Enter fullscreen mode Exit fullscreen mode

Props

Suppose that we want to greet the user and not the world. Introducing props! Data can be passed to child components using any Clojure data type.

(defn greet-cmp [user-name]
  [:div.banner
    [:h1 "Hello, " user-name "!"]])
Enter fullscreen mode Exit fullscreen mode

Keys

Now suppose that we want to list the user's contacts. We can easily do this via the for macro in Clojure. Just make sure to include the key of each list item by prepending ^{:key id}. Otherwise, you will get a warning in the console.

(defn contacts-cmp [connections]
  [:ul
   (for [con connections]
     ^{:key (:id con)} [:li "Contact: " (:username con)])])
Enter fullscreen mode Exit fullscreen mode

Managing state

Remember Form 2 components - how they can be used to initialize some local state. Here, we are initializing a seconds atom that will increment by 1 each second.

Reagent atoms (r/atom) are similar to regular Clojure atoms in the sense that you can use swap! or reset! on them. The difference is that Reagent atoms are reactive. All components that dereference a Reagent atom will be re-rendered whenever the value of the atom changes.

(defn counter-cmp []
  (let [seconds (r/atom 0)]
    (.setInterval js/window #(swap! seconds inc) 1000)
    (fn []
      [:div
       "Seconds Elapsed: " @seconds])))
Enter fullscreen mode Exit fullscreen mode

Warmly,
DH

Top comments (0)