DEV Community

Cover image for Reagent 101 / pt. 1 / Hiccup
icncsx
icncsx

Posted on • Edited on

Reagent 101 / pt. 1 / Hiccup

Reagent is a light-weight interface for building React components using Clojure. Here is how you start any Reagent app.

  1. Require the relevant reagent modules - namely reagent.dom and reagent.core. This is similar to what we did in JS land when we imported from react and react-dom.

  2. Mount a component to a target div - typically with an id of root or app.

// JS
import React from "react";
import ReactDOM from "react-dom";
import App from "./App"

ReactDOM.render(<App />, document.getElementById("root");
Enter fullscreen mode Exit fullscreen mode
;; Clojure
(ns demo.core
  (:require
   [reagent.dom :as rdom]
   [reagent.core :as r]
   [demo.core.app :refer [app-view]]
))

(defn render! []
  (when-let [element
(js/document.getElementById "root")]
    (rdom/render [app-view] element)))
Enter fullscreen mode Exit fullscreen mode

Do you see the similarity in form and naming convention?

Now you obviously need to define your actual component. Currently, <App/> nor app-view refers to anything. We already know what a React component looks like in JS land. What do you think that looks like in Reagent land?

// stateful
import React, { Component } from "react";

class App extends Component  {
  constructor(props) {
    super(props)
    // ..
  }
  render() {
    // ..
  }
}

// stateless
import React from "react";
const App = (props) => {
  // ..
  return (
  // ..
  )
}
Enter fullscreen mode Exit fullscreen mode

In React, there are 2 canonical forms of defining a component: stateful and stateless. In Reagent, there are 3.

We call them Form 1, Form 2, and Form 3. I know what you're thinking! Is there a better name? Not that I know of unfortunately.

Before we get into those 3 forms, we need to talk about something even more important: Hiccup.

What is Hiccup?

Hiccup is a Clojure library that enables us to represent HTML using Clojure vectors. In HTML and JSX, you have tags <>. In Clojure, you have vectors [].

Here are some examples. I have the Hiccup syntax mapped to HTML.

;; Hiccup
[:h1 "Hello, world!"]

[:ul
  [:li "First"]
  [:li "Second"]
  [:li "Third"]]
Enter fullscreen mode Exit fullscreen mode
<!--HTML-->
<h1>Hello, world!</h1>

<ul>
  <li>First</li>
  <li>Second</li>
  <li>Third</li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Ok, what about attributes? For those, we use a map. One benefit you get from using Hiccup instead of JSX is that prop names stay the same. Use :class not className, :text-align not textAlign, and on-click not onClick.

;; Hiccup
[:div { :class "main" }
   :h1 { :style { :color "red" :text-align "center" } } "Hello, world!]
Enter fullscreen mode Exit fullscreen mode
<!--HTML-->
<div class="main">
  <h1 style="color:red; text-align: center">Hello, world!</h1>
</div>
Enter fullscreen mode Exit fullscreen mode

Now that we know how to define basic UI using Hiccup, we are ready to talk about the 3 forms of defining Reagent components. And we will move that discussion to a future post.

Hic! Hic! cup... I need a cup of water.

I'm out.

PS: part 2 of the Reagent 101 series is out.

Warmly,
DH

Top comments (0)