Reagent is a light-weight interface for building React components using Clojure. Here is how you start any Reagent app.
Require the relevant reagent modules - namely
reagent.dom
andreagent.core
. This is similar to what we did in JS land when we imported fromreact
andreact-dom
.Mount a component to a target
div
- typically with an id ofroot
orapp
.
// JS
import React from "react";
import ReactDOM from "react-dom";
import App from "./App"
ReactDOM.render(<App />, document.getElementById("root");
;; 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)))
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 (
// ..
)
}
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"]]
<!--HTML-->
<h1>Hello, world!</h1>
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
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!]
<!--HTML-->
<div class="main">
<h1 style="color:red; text-align: center">Hello, world!</h1>
</div>
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)