### Install and Run Project
Source: https://github.com/reagent-project/reagent/blob/master/examples/react-mde/README.md
Commands to install dependencies and start the development server.
```sh
npm install
npm run dev
```
--------------------------------
### Install Karma CLI
Source: https://github.com/reagent-project/reagent/blob/master/doc/development.md
Install the Karma command-line interface globally to manage browser testing.
```bash
npm install -g karma-cli
```
--------------------------------
### Install React with npm
Source: https://github.com/reagent-project/reagent/blob/master/README.md
When using tools like Shadow-cljs, install React and react-dom using npm. It is generally safe to use the latest minor or patch versions of React.
```bash
npm i react@19.2.3 react-dom@19.2.3
```
--------------------------------
### Use reagent.dom.client API for Rendering
Source: https://github.com/reagent-project/reagent/blob/master/doc/2.0-upgrade.md
Replace `reagent.dom/render` with the new `reagent.dom.client` API calls. This example shows how to create a root and render a Reagent component.
```clojure
(ns example.core
(:require [reagent.dom.client :as rdomc]))
(defn view []
[:div "Hello world"])
(defonce root (rdomc/create-root (.getElementById js/document "app")))
(defn ^:export run []
(rdomc/render root [view]))
```
--------------------------------
### Reagent Ratom Input Example
Source: https://github.com/reagent-project/reagent/blob/master/doc/WhenDoComponentsUpdate.md
Demonstrates a component that takes a ratom as input. Reagent watches this ratom and re-renders the component when its value changes.
```clojure
(def name (reagent.ratom/atom "Bear"))
(defn ask-for-forgiveness
[] ;; <--- no props
[:div "Please " @name " with me"])
```
--------------------------------
### JSX Example
Source: https://github.com/reagent-project/reagent/blob/master/doc/Security.md
A basic example of rendering a title from a response object using JSX.
```jsx
{response.title}
```
--------------------------------
### Using Hooks and RAtoms with :f> Shortcut
Source: https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md
This example demonstrates using the `:f>` shortcut to create function components that support both React Hooks and Reagent's RAtoms. Ensure the component is defined as a ClojureScript function.
```clojure
;; This is used with :f> so both Hooks and RAtoms work here
(defn example []
(let [[count set-count] (react/useState 0)]
[:div
[:p "You clicked " count " times"]
[:button
{:on-click #(set-count inc)}
"Click"]]))
(defn root []
[:div
[:f> example]])
```
--------------------------------
### Complete TodoMVC Example in ClojureScript
Source: https://context7.com/reagent-project/reagent/llms.txt
This snippet provides the full implementation of a TodoMVC application using Reagent. It includes state management for todos, input handling, editing, filtering, and rendering. Ensure Reagent and React are properly set up.
```clojure
(ns todomvc.core
(:require ["react" :as react]
[clojure.string :as str]
[reagent.core :as r]
[reagent.dom.client :as rdomc]))
(defonce todos (r/atom (sorted-map)))
(defonce counter (r/atom 0))
(defn add-todo [text]
(let [id (swap! counter inc)]
(swap! todos assoc id {:id id :title text :done false})))
(defn toggle [id] (swap! todos update-in [id :done] not))
(defn save [id title] (swap! todos assoc-in [id :title] title))
(defn delete [id] (swap! todos dissoc id))
;; Form-2: local val atom, inner fn receives updated props
(defn todo-input [{:keys [title on-save on-stop]}]
(let [val (r/atom title)]
(fn [{:keys [id class placeholder]}]
(let [commit #(let [v (str/trim @val)]
(when-not (empty? v) (on-save v))
(reset! val "")
(when on-stop (on-stop)))]
[:input {:value @val
:id id
:class class
:placeholder placeholder
:on-blur commit
:on-change #(reset! val (-> % .-target .-value))
:on-key-down #(case (.-which %)
13 (commit)
27 (do (reset! val "") (when on-stop (on-stop)))
nil)}]))))
;; Functional component (:f>) using useEffect to auto-focus
(defn todo-edit [props]
(let [ref (react/useRef)]
(react/useEffect (fn [] (.focus (.-current ref))) js/undefined))
[todo-input (assoc props :input-ref ref)])
;; Form-2 with local editing state
(defn todo-item []
(let [editing (r/atom false)]
(fn [{:keys [id done title]}]
[:li {:class [(when done "completed") (when @editing "editing")]}
[:div.view
[:input.toggle {:type "checkbox" :checked done :on-change #(toggle id)}]
[:label {:on-double-click #(reset! editing true)} title]
[:button.destroy {:on-click #(delete id)}]]
(when @editing
[:f> todo-edit {:title title
:on-save #(save id %)
:on-stop #(reset! editing false)}])])))
(defn todo-app []
(let [filt (r/atom :all)]
(fn []
(let [items (vals @todos)
done (->> items (filter :done) count)
active (- (count items) done)]
[:section#todoapp
[:header
[:h1 "todos"]
[todo-input {:placeholder "What needs to be done?" :on-save add-todo}]]
[:ul#todo-list
(for [todo (filter (case @filt :active (complement :done)
:done :done identity) items)]
^{:key (:id todo)} [todo-item todo])]
[:footer
[:span [:strong active] " items left"]
[:ul
(for [f [:all :active :done]]
^{:key f} [:li [:a {:class (when (= f @filt) "selected")
:on-click #(reset! filt f)} (name f)]])]
(when (pos? done)
[:button {:on-click #(swap! todos (fn [m] (into {} (remove (comp :done val) m))))}
"Clear completed"])]]))))
(defonce root (delay (rdomc/create-root (.getElementById js/document "app"))))
(defn ^:export run []
(add-todo "Learn Reagent")
(add-todo "Build something great")
(rdomc/render @root [todo-app]))
```
--------------------------------
### Mount Reagent Component to DOM
Source: https://github.com/reagent-project/reagent/blob/master/README.md
Example of how to render a Reagent component into the browser's DOM. This typically targets the `body` element.
```clojure
(defn mount-it []
(rd/render [parent] (.-body js/document)))
```
--------------------------------
### Using handler-fn Macro - Basic Usage
Source: https://github.com/reagent-project/reagent/wiki/Beware-Event-Handlers-Returning-False
This example shows the basic usage of the `handler-fn` macro. By wrapping the handler's body, it ensures that the handler returns `nil` and does not accidentally trigger event propagation cancellation.
```clojure
:on-mouse-out (handler-fn (reset! mouse-over-atom false))
```
--------------------------------
### Watch Command for Shadow-CLJS
Source: https://github.com/reagent-project/reagent/blob/master/examples/react-transition-group/README.md
Use this command to start the Shadow-CLJS build process in watch mode. This is often a prerequisite for running React applications built with Shadow-CLJS.
```bash
npx shadow-cljs watch app
```
--------------------------------
### Reagent Color Demo with Timing Wrapper
Source: https://github.com/reagent-project/reagent/blob/master/doc/BatchingAndTiming.md
This example showcases asynchronous rendering with a color chooser and a dynamic palette. It uses a timing wrapper to measure and display render times, illustrating smooth updates even with many elements. The `timing-wrapper` function instruments a component to record its render duration.
```clojure
(ns example
(:require [reagent.core :as r]))
(defn timing-wrapper [f]
(let [start-time (r/atom nil)
render-time (r/atom nil)
now #(.now js/Date)
start #(reset! start-time (now))
stop #(reset! render-time (- (now) @start-time))
timed-f (with-meta f
{:constructor start
:UNSAFE_component-will-update start
:component-did-mount stop
:component-did-update stop})]
(fn []
[:div
[:p [:em "render time: " @render-time "ms"]]
[timed-f]])))
(def base-color (r/atom {:red 130 :green 160 :blue 120}))
(def ncolors (r/atom 20))
(def random-colors (r/atom nil))
(defn to-rgb [{:keys [red green blue]}]
(let [hex #(str (if (< % 16) "0")
(-> % js/Math.round (.toString 16)))]
(str "#" (hex red) (hex green) (hex blue))))
(defn tweak-color [{:keys [red green blue]}]
(let [rnd #(-> (js/Math.random) (* 256))
tweak #(-> % (+ (rnd)) (/ 2) js/Math.floor)]
{:red (tweak red) :green (tweak green) :blue (tweak blue)}))
(defn reset-random-colors [color]
(reset! random-colors
(repeatedly #(-> color tweak-color to-rgb))))
(defn color-choose [color-part]
[:div.color-slider
(name color-part) " " (color-part @base-color)
[:input {:type "range" :min 0 :max 255
:value (color-part @base-color)
:on-change (fn [e]
(swap! base-color assoc
color-part (-> e .-target .-value int))
(reset-random-colors @base-color))}])
(defn ncolors-choose []
[:div.color-slider
"number of color divs " @ncolors
[:input {:type "range" :min 0 :max 500
:value @ncolors
:on-change #(reset! ncolors (-> % .-target .-value int))}])
(defn color-plate [color]
[:div.color-plate
{:style {:background-color color}}])
(defn palette []
(let [color @base-color
n @ncolors]
[:div
[:p "base color: "]
[color-plate (to-rgb color)]
[:div.color-samples
[:p n " random matching colors:"]
(map-indexed (fn [k v]
^{:key k} [color-plate v])
(take n @random-colors))]]))
(defn color-demo []
(reset-random-colors @base-color)
(fn []
[:div
[:h2 "Matching colors"]
[color-choose :red]
[color-choose :green]
[color-choose :blue]
[ncolors-choose]
[timing-wrapper palette]]))
```
--------------------------------
### Reagent Implementation of React Fragment Example
Source: https://github.com/reagent-project/reagent/blob/master/doc/CreatingReagentComponents.md
This snippet demonstrates how to define a component in Reagent that utilizes a React Fragment (`:<>`) to return multiple sibling elements, similar to the `Columns` example in React documentation.
```clojurescript
(defn columns
[]
[:<>
[:td "Hello"]
[:td "World"]]
```
--------------------------------
### Creating a Reaction with the reaction Macro
Source: https://github.com/reagent-project/reagent/blob/master/doc/ManagingState.md
Illustrates using the `reagent.ratom/reaction` macro for a more concise way to create reactions. This example creates a boolean reaction that checks if two input atoms are populated.
```clojure
(let [username (reagent/atom "")
password (reagent/atom "")
fields-populated? (reagent.ratom/reaction (every? not-empty [@username @password]))]
[:div "Is username and password populated ?" @fields-populated?])
```
--------------------------------
### Build Reagent Package
Source: https://github.com/reagent-project/reagent/blob/master/doc/development.md
Install the Reagent package locally after building it. This command overwrites versions released on Clojars in your local Maven repository.
```bash
lein install
```
--------------------------------
### Hydrating React DOM with Reagent
Source: https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md
This example shows how to hydrate a client-side React application using Reagent. It attaches event listeners to existing server-rendered HTML.
```clojure
(react-dom/hydrate (r/as-element [main-component]) container)
```
--------------------------------
### Reagent Timer Component (Form-2)
Source: https://github.com/reagent-project/reagent/blob/master/doc/CreatingReagentComponents.md
Use this form when a component needs setup or local state. The outer function initializes state, and the inner render function closes over it.
```clojure
(defn timer-component []
(let [seconds-elapsed (reagent/atom 0)] ;; setup, and local state
(fn [] ;; inner, render function is returned
(js/setTimeout #(swap! seconds-elapsed inc) 1000)
[:div "Seconds Elapsed: " @seconds-elapsed])))
```
--------------------------------
### Minimal dangerouslySetInnerHTML Example in Reagent
Source: https://github.com/reagent-project/reagent/blob/master/doc/FAQ/dangerouslySetInnerHTML.md
Use this snippet to render raw HTML content within a Reagent component. Ensure you understand the security implications before using this feature.
```clojure
[:div
{:dangerouslySetInnerHTML
(r/unsafe-html "")}]
```
--------------------------------
### Component with Delayed Rendering Function
Source: https://github.com/reagent-project/reagent/blob/master/README.md
Shows how a component function can return another function for delayed rendering, useful for setup tasks. This avoids direct use of React lifecycle methods.
```clojure
(defn timer-component []
(let [seconds-elapsed (r/atom 0)]
(fn []
(js/setTimeout #(swap! seconds-elapsed inc) 1000)
[:div
"Seconds Elapsed: " @seconds-elapsed])))
```
--------------------------------
### Memoized Reactive Computations with `track` and `track!`
Source: https://context7.com/reagent-project/reagent/llms.txt
Use `track` for lazy, cached computations that re-evaluate only when their ratom dependencies change and their output value changes. Use `track!` for eager computations that run immediately and continuously until disposed. This example demonstrates tracking lists and individual items, and an eager logger.
```clojure
(ns example.tracking
(:require [reagent.core :as r]))
(defonce app-state (r/atom {:people {1 {:name "Alice"}
2 {:name "Bob"}
3 {:name "Carol"}}}))
(defn people [] (:people @app-state))
(defn person-keys [] (-> @(r/track people) keys sort))
(defn person [id] (-> @(r/track people) (get id)))
;; Only re-renders when person-keys list changes
(defn name-list []
(let [ids @(r/track person-keys)])
[:ul
(for [id ids]
^{:key id} [:li @(r/track person id) " — " (:name @(r/track person id))])])
;; Eager tracker: logs every state change until disposed
(defonce logger (r/track! #(js/console.log "State:" (str @app-state))))
;; Stop tracking:
;; (r/dispose! logger)
```
--------------------------------
### Component with Event Listener using with-let
Source: https://github.com/reagent-project/reagent/blob/master/doc/CreatingReagentComponents.md
Demonstrates creating a component that sets up a mouse move event listener and cleans it up when the component unmounts, using `r/with-let` for managing the listener and a local atom.
```clojure
(defn mouse-pos-comp []
(r/with-let [pointer (r/atom nil)
handler #(swap! pointer assoc
:x (.-pageX %)
:y (.-pageY %))
_ (.addEventListener js/document "mousemove" handler)]
[:div
"Pointer moved to: "
(str @pointer)]
(finally
(.removeEventListener js/document "mousemove" handler))))
```
--------------------------------
### Prepare Test Environments
Source: https://github.com/reagent-project/reagent/blob/master/doc/development.md
Execute the script to set up different environments required for running tests.
```bash
./prepare-tests.sh
```
--------------------------------
### Creating a Reaction with make-reaction
Source: https://github.com/reagent-project/reagent/blob/master/doc/ManagingState.md
Shows how to create a reaction using `reagent.ratom/make-reaction` to derive a value from a state atom. This reaction will update automatically when the relevant part of the `app-state` changes.
```clojure
(def app-state (reagent/atom {:state-var-1 {:var-a 2
:var-b 3}
:state-var-2 {:var-a 7
:var-b 9}}))
(def app-var2a-reaction (reagent.ratom/make-reaction
#(get-in @app-state [:state-var-2 :var-a])))
(defn component-using-make-reaction []
[:div
[:div "component-using-make-reaction"]
[:div "state-var-2 - var-a : " @app-var2a-reaction]])
```
--------------------------------
### Continuous State Monitoring with track!
Source: https://github.com/reagent-project/reagent/blob/master/doc/ManagingState.md
Shows how to use `r/track!` to continuously monitor changes in application state. The provided function is invoked immediately and whenever its dependencies change. Use `r/dispose!` to stop the tracking.
```clojure
(defn log-app-state []
(prn @app-state))
```
```clojure
(defonce logger (r/track! log-app-state))
```
```clojure
(r/dispose! logger)
```
--------------------------------
### Reagent Hiccup Data Structures
Source: https://github.com/reagent-project/reagent/blob/master/doc/Security.md
Demonstrates regular use of Hiccup for creating nested elements and an example of potentially unsafe HTML injection.
```clojure
;; Regular use
(let [h [:h1 "Hello"]]
[:div h [:p "world"]])
```
```clojure
;; Data from an API
(def title (r/atom nil))
;; Some code that retrieves an EDN/Transit value from an external API or localStorage
;; and stores the decoded value into the atom:
(reset! title [:div {:dangerouslySetInnerHTML {:__html "
"}}])
[:div [:h1 @title]]
```
```clojure
;; One safe approach
[:div [:h1 (str @title)]]
```
--------------------------------
### Tracked Component with Event Listener using with-let
Source: https://github.com/reagent-project/reagent/blob/master/doc/CreatingReagentComponents.md
Shows how to combine `r/with-let` with `r/track` to create a component that tracks a reactive value, ensuring cleanup logic runs when the tracked component is unmounted.
```clojure
(defn mouse-pos []
(r/with-let [pointer (r/atom nil)
handler #(swap! pointer assoc
:x (.-pageX %)
:y (.-pageY %))
_ (.addEventListener js/document "mousemove" handler)]
@pointer
(finally
(.removeEventListener js/document "mousemove" handler))))
(defn tracked-pos []
[:div
"Pointer moved to: "
(str @(r/track mouse-pos))])
```
--------------------------------
### Parent Component Using a Reagent Component
Source: https://github.com/reagent-project/reagent/blob/master/doc/WhenDoComponentsUpdate.md
Illustrates a parent component rendering multiple instances of a child component ('greet'). One instance receives a static prop, while the other receives a dynamically generated prop, demonstrating how props can change over time and trigger re-renders.
```clojure
(defn greet-family
[]
[:div
[greet "Dad"]
[greet (str "Bro-" (rand-int 10))]])
```
--------------------------------
### Create and Use Reagent Compiler
Source: https://github.com/reagent-project/reagent/blob/master/doc/ReagentCompiler.md
Defines a compiler with functional component support and demonstrates its usage with `reagent.dom/render` and `reagent.core/as-element`. It also shows how to set this compiler as the default.
```clojure
(def functional-compiler (reagent.core/create-compiler {:function-components true}))
;; Using the option
(reagent.dom/render [main] div functional-compiler)
(reagent.core/as-element [main] functional-compiler)
;; Setting compiler as the default
(reagent.core/set-default-compiler! functional-compiler)
```
--------------------------------
### Create React Elements using Reagent
Source: https://github.com/reagent-project/reagent/blob/master/doc/InteropWithReact.md
Demonstrates multiple ways to create React elements using Reagent's `create-element` and `as-element` functions, suitable for direct use or within Hiccup forms.
```clojure
(defn integration []
[:div
[:div.foo "Hello " [:strong "world"]]
(r/create-element "div"
#js{:className "foo"}
"Hello "
(r/create-element "strong"
#js{}
"world"))
(r/create-element "div"
#js{:className "foo"}
"Hello "
(r/as-element [:strong "world"]))
[:div.foo "Hello " (r/create-element "strong"
#js{}
"world")]])
(defn mount-root []
(rdom/render [integration]
(.getElementById js/document "app")))
```
--------------------------------
### Creating a Parent Component with Multiple Children (Square Brackets)
Source: https://github.com/reagent-project/reagent/blob/master/doc/UsingSquareBracketsInsteadOfParens.md
This function creates a parent component that renders multiple child `greet` components. Using square brackets ensures each `greet` child is a distinct React component, allowing independent re-renders.
```clojure
(defn greet-family-square
[member1 member2 member3]
[:div
[greet member1]
[greet member2]
[greet member3]])
```
--------------------------------
### Correctly Using HTML Entity with goog.string
Source: https://github.com/reagent-project/reagent/blob/master/doc/FAQ/UsingAnEntity.md
Require the `goog.string` module and use `unescapeEntities` to correctly render HTML entities. This method relies on the DOM, so it may not work in Node.js environments without additional setup.
```clojure
(:require [goog.string :as gstring])
```
```clojure
[:div "hello" (gstring/unescapeEntities " ") "there"]
```
--------------------------------
### Reagent Context Provider and Consumer
Source: https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md
Demonstrates creating a React context in Reagent and using its Provider and Consumer components.
```cljs
(defonce my-context (react/createContext "default"))
(def Provider (.-Provider my-context))
(def Consumer (.-Consumer my-context))
(rdom/render
[:> Provider {:value "bar"}
[:> Consumer {}
(fn [v]
(r/as-element [:div "Context: " v]))]]
container)
```
--------------------------------
### Focused Atom Slices with `cursor`
Source: https://context7.com/reagent-project/reagent/llms.txt
Use `cursor` to create a focused view into a nested ratom. Components dereferencing a cursor re-render only when their specific path within the parent ratom changes, improving performance. This example shows editing and toggling nested state.
```clojure
(ns example.cursors
(:require [reagent.core :as r]
[reagent.dom.client :as rdomc]))
(defonce state (r/atom {:user {:name "Alice" :age 30}
:settings {:theme "dark"}}))
;; Cursor into nested path
(def name-cursor (r/cursor state [:user :name]))
(def theme-cursor (r/cursor state [:settings :theme]))
(defn name-editor []
[:div
[:label "Name: "]
[:input {:value @name-cursor
:on-change #(reset! name-cursor (-> % .-target .-value))}]]])
(defn theme-toggle []
[:button
{:on-click #(swap! theme-cursor {"dark" "light" "light" "dark"})}
"Theme: " @theme-cursor])
;; name-editor re-renders only when [:user :name] changes
;; theme-toggle re-renders only when [:settings :theme] changes
(defonce root (rdomc/create-root (.getElementById js/document "app")))
(rdomc/render root [:div [name-editor] [theme-toggle]])
```
--------------------------------
### Creating and Using Reagent Cursors
Source: https://github.com/reagent-project/reagent/blob/master/doc/ManagingState.md
Demonstrates how to create a state atom and then derive cursors from it. Components using cursors only re-render when the specific part of the state they are interested in changes.
```clojure
;; First create a ratom
(def state (reagent/atom {:foo {:bar "BAR"}
:baz "BAZ"
:quux "QUUX"}))
;; Now create a cursor
(def bar-cursor (reagent/cursor state [:foo :bar]))
(defn quux-component []
(js/console.log "quux-component is rendering")
[:div (:quux @state)])
(defn bar-component []
(js/console.log "bar-component is rendering")
[:div @bar-cursor])
(defn mount-root []
(rdom/render [:div [quux-component] [bar-component]]
(.getElementById js/document "app"))
(js/setTimeout (fn [] (swap! state assoc :baz "NEW BAZ")) 1000)
(js/setTimeout (fn [] (swap! state assoc-in [:foo :bar] "NEW BAR")) 2000))
```
--------------------------------
### Run Full Test Suite
Source: https://github.com/reagent-project/reagent/blob/master/doc/development.md
Execute the script to run all tests in the Reagent project.
```bash
./run-tests.sh
```
--------------------------------
### Form-2 Components with Local State and Cleanup
Source: https://context7.com/reagent-project/reagent/llms.txt
Form-2 components use an outer function to initialize per-instance local state and return an inner render function. Use `r/with-let` for managing resources with cleanup via `finally`.
```clojure
(ns example.timer
(:require [reagent.core :as r]))
;; Outer fn runs once; inner fn runs on every re-render
(defn timer-component []
(let [seconds (r/atom 0)
interval (js/setInterval #(swap! seconds inc) 1000)]
(r/with-let [_ nil] ; Use `with-let` for resource management
[:div "Elapsed: " @seconds "s"]
(finally (js/clearInterval interval))))) ; Cleanup via finally
;; Alternative using explicit Form-2 with cleanup via lifecycle
(defn stopwatch []
(let [elapsed (r/atom 0)]
(fn [] ;; <-- inner render function; must repeat params if any
[:div
[:span "Time: " @elapsed "s"]
[:button {:on-click #(reset! elapsed 0)} "Reset"]])))
```
--------------------------------
### Creating a Parent Component with Multiple Children (Parentheses)
Source: https://github.com/reagent-project/reagent/blob/master/doc/UsingSquareBracketsInsteadOfParens.md
This function also creates a parent component rendering multiple `greet` children, but uses parentheses `()` for the hiccup. This approach incorporates all children into a single data structure, causing them to re-render with the parent.
```clojure
(defn greet-family-round
[member1 member2 member3]
[:div
(greet member1)
(greet member2)
(greet member3)])
```
--------------------------------
### React Fragment Syntax
Source: https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md
Shows the equivalent JSX and Reagent syntax for React Fragments.
```js
function example() {
return (
);
}
```
```cljs
(defn example []
[:<>
[child-a]
[child-b]
[child-c]])
```
--------------------------------
### Local State with Cleanup using `with-let`
Source: https://context7.com/reagent-project/reagent/llms.txt
Use `with-let` for bindings that execute once per component instance and include an optional `finally` clause for cleanup on unmount. This is useful for managing local state and side effects like event listeners.
```clojure
(ns example.mouse
(:require [reagent.core :as r]))
(defn mouse-tracker []
(r/with-let [pos (r/atom {:x 0 :y 0})
handler (fn [e]
(reset! pos {:x (.-pageX e) :y (.-pageY e)}))
_ (.addEventListener js/document "mousemove" handler)]
[:div
"Mouse: " (:x @pos) ", " (:y @pos)]
(finally
(.removeEventListener js/document "mousemove" handler))))
```
--------------------------------
### Create React Components from Reagent Components
Source: https://github.com/reagent-project/reagent/blob/master/doc/InteropWithReact.md
Illustrates how to convert Reagent components into React components using `reagent/reactify-component`. This is useful for exporting Reagent logic to be used in pure React contexts.
```clojure
(defn exported [props]
[:div "Hi, " (:name props)])
(def react-comp (r/reactify-component exported))
(defn could-be-jsx []
(r/create-element react-comp #js{:name "world"}))
```
--------------------------------
### Integrate Higher-Order React Components with Reagent
Source: https://github.com/reagent-project/reagent/blob/master/doc/InteropWithReact.md
Demonstrates how to use both `adapt-react-class` and `reactify-component` to integrate React components that employ the decorator pattern, such as those from React DnD.
```clojure
(def react-dnd-component
(let [decorator (DragDropContext HTML5Backend)]
(reagent/adapt-react-class
(decorator (reagent/reactify-component top-level-component)))))
```
```javascript
import HTML5Backend from 'react-dnd-html5-backend';
import { DragDropContext } from 'react-dnd';
class TopLevelComponent {
/* ... */
}
export default DragDropContext(HTML5Backend)(TopLevelComponent);
```
--------------------------------
### State Management with Atoms
Source: https://github.com/reagent-project/reagent/blob/master/README.md
Demonstrates state management in Reagent using `reagent.core/atom`. Components that dereference atoms automatically re-render when the atom's value changes.
```clojure
(defonce click-count (r/atom 0))
(defn state-ful-with-atom []
[:div {:on-click #(swap! click-count inc)}
"I have been clicked " @click-count " times."])
```
--------------------------------
### Reagent State Management with track
Source: https://github.com/reagent-project/reagent/blob/master/doc/ManagingState.md
Demonstrates how to use `r/track` to create reactive values from functions that depend on Reagent atoms. This optimizes component re-renders by only updating when the tracked value changes. Ensure the first argument to `track` is a named function.
```clojure
(ns example.core
(:require [reagent.core :as r]))
(defonce app-state (r/atom {:people
{1 {:name "John Smith"}
2 {:name "Maggie Johnson"}}}))
(defn people []
(:people @app-state))
(defn person-keys []
(-> @(r/track people)
keys
sort))
(defn person [id]
(-> @(r/track people)
(get id)))
(defn name-comp [id]
(let [p @(r/track person id)]
[:li
(:name p)]))
(defn name-list []
(let [ids @(r/track person-keys)]
[:ul
(for [i ids]
^{:key i} [name-comp i])]))
```
--------------------------------
### Server-Side Rendering with Reagent
Source: https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md
This code demonstrates how to perform server-side rendering using Reagent. It converts a main Reagent component into an HTML string.
```clojure
(reagent.dom.server/render-to-string
(reagent.core/as-element [main-component]))
```
--------------------------------
### Compose Reagent Components
Source: https://github.com/reagent-project/reagent/blob/master/README.md
Illustrates how to use one Reagent component within another, enabling hierarchical UI structures. Ensure the called component is defined.
```clojure
(defn calling-component []
[:div "Parent component"
[some-component]])
```
--------------------------------
### Define a Simple Reagent Component
Source: https://github.com/reagent-project/reagent/blob/master/doc/CreatingReagentComponents.md
Create a basic component by defining a ClojureScript function that accepts data as parameters and returns Hiccup (HTML structure). This is the most straightforward method for component creation.
```clojurescript
(defn greet
[name]
[:div "Hello " name])
```
--------------------------------
### Reagent Render Loop Hooks
Source: https://context7.com/reagent-project/reagent/llms.txt
Schedule callbacks using `r/next-tick` (before next paint) or `r/after-render` (after render completes). `r/flush` forces an immediate synchronous render, useful for testing.
```clojure
(ns example.timing
(:require [reagent.core :as r]))
(defonce ui-state (r/atom {:value "" :focused false}))
(defn timed-input []
[:input
{:value (:value @ui-state)
:on-change (fn [e]
(let [v (-> e .-target .-value)]
(swap! ui-state assoc :value v)
;; Run before next paint — good for reading layout
(r/next-tick #(js/console.log "pre-render value:" v))
;; Run after render completes — good for DOM side-effects
(r/after-render #(js/console.log "post-render DOM updated"))))}])
;; Force immediate synchronous render (useful in tests)
(defn set-and-flush! [new-val]
(reset! ui-state {:value new-val :focused false})
(r/flush)
;; DOM is now updated synchronously
(js/console.log "DOM updated:" (.-value (.getElementById js/document "my-input"))))
```
--------------------------------
### Adapt React Class Components for Reagent
Source: https://github.com/reagent-project/reagent/blob/master/doc/InteropWithReact.md
Shows how to use `reagent/adapt-react-class` to wrap React class components, allowing them to be used within Reagent's Hiccup syntax. The `:>` shorthand is also demonstrated.
```clojure
(defn top-articles [articles]
[(reagent/adapt-react-class FlipMove)
{:duration 750
:easing "ease-out"}
articles])
```
```clojure
(defn top-articles [articles]
[:> FlipMove
{:duration 750
:easing "ease-out"}
articles])
```
```javascript
const TopArticles = ({ articles }) => (
{articles}
);
```
--------------------------------
### Mounting Reagent Components with React 19 Client API
Source: https://context7.com/reagent-project/reagent/llms.txt
Primary entry point for React 19 applications. Creates a React root attached to a DOM node and renders a Reagent component tree. Use `defonce` for the root to persist across hot-reloads.
```clojure
(ns example.app
(:require [reagent.core :as r]
[reagent.dom.client :as rdomc]))
(defn app []
[:div.container
[:h1 "Hello, Reagent!"]
[:p "Built with React 19 + ClojureScript"]])
;; Create root once; re-render on hot-reload
(defonce react-root (rdomc/create-root (.getElementById js/document "app")))
(defn ^:export ^:dev/after-load run []
(rdomc/render react-root [app]))
;; To unmount:
;; (rdomc/unmount react-root)
;; Optional: enable React StrictMode
;; (rdomc/render react-root [app] nil true)
```
--------------------------------
### `reagent.dom.client/create-root` and `reagent.dom.client/render` — Mount components (React 19)
Source: https://context7.com/reagent-project/reagent/llms.txt
Creates a React root attached to a DOM node and renders a Reagent component tree into it. This is the primary entry point for React 19 applications.
```APIDOC
## `reagent.dom.client/create-root` and `reagent.dom.client/render` — Mount components (React 19)
Creates a React root attached to a DOM node and renders a Reagent component tree into it. This is the primary entry point for React 19 applications.
```clojure
(ns example.app
(:require [reagent.core :as r]
[reagent.dom.client :as rdomc]))
(defn app []
[:div.container
[:h1 "Hello, Reagent!"]
[:p "Built with React 19 + ClojureScript"]])
;; Create root once; re-render on hot-reload
(defonce react-root (rdomc/create-root (.getElementById js/document "app")))
(defn ^:export ^:dev/after-load run []
(rdomc/render react-root [app]))
;; To unmount:
;; (rdomc/unmount react-root)
;; Optional: enable React StrictMode
;; (rdomc/render react-root [app] nil true)
```
```
--------------------------------
### Render a Form-3 Component
Source: https://github.com/reagent-project/reagent/blob/master/doc/CreatingReagentComponents.md
Demonstrates how to render a Form-3 component directly or as a child within another Reagent component. Ensure the Reagent class is placed in square brackets to trigger rendering.
```clojure
(reagent/render
[my-component 1 2 3] ;; pass in x y z
(.-body js/document))
```
```clojure
(defn homepage []
[:div
[:h1 "Welcome"]
[my-component 1 2 3]]) ;; Be sure to put the Reagent class in square brackets to force it to render!
```
--------------------------------
### Generating Hiccup Programmatically with `into` and `map`
Source: https://github.com/reagent-project/reagent/blob/master/doc/UsingSquareBracketsInsteadOfParens.md
This rewrite of `greet-family-round` demonstrates generating hiccup more dynamically. It uses `into` to prepend a `:div` to a sequence of hiccup generated by mapping the `greet` function over a list of members.
```clojure
(defn greet-family-round-2
[& members]
(into [:div] (map greet members)))
```
--------------------------------
### Add Static Methods/Properties to `create-class`
Source: https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md
Modify the return value of `r/create-class` to add custom static methods or properties. While `create-class` handles built-in static methods, others require manual assignment using `set!`.
```clojure
(let [klass (r/create-class ...)])
(set! (.-static-property klass) "foobar")
(set! (.-static-method klass) (fn [param] ...))
klass)
```
--------------------------------
### Component with Dynamic Class Names
Source: https://github.com/reagent-project/reagent/blob/master/README.md
Demonstrates how to use dynamic class names in Reagent components, supporting collections of classes and automatic removal of nil values since version 0.8.
```clojure
[:div {:class ["a-class" (when active? "active") "b-class"]}])
```
--------------------------------
### reagent.core/adapt-react-class and :> shorthand
Source: https://context7.com/reagent-project/reagent/llms.txt
Enables the use of React components within Reagent's Hiccup syntax by wrapping them. The `:>` shorthand provides an inline alternative for the same functionality.
```APIDOC
## `reagent.core/adapt-react-class` and `:>` shorthand — Use React components in Hiccup
Wraps a native React component so it can be used in the first position of a Hiccup vector. The `:>` shorthand does the same thing inline.
```clojure
(ns example.interop
(:require ["react-flip-move" :default FlipMove]
["react-select" :default Select]
[reagent.core :as r]))
(def flip-move (r/adapt-react-class FlipMove))
(defn animated-list [items]
[flip-move {:duration 750 :easing "ease-out"}
(for [item items]
^{:key (:id item)} [:div.item (:name item)])])
;; Using the :> shorthand — equivalent to adapt-react-class
(defn select-input [value on-change]
[:> Select
{:value value
:onChange on-change
:options [{:value "clj" :label "Clojure"}
{:value "cljs" :label "ClojureScript"}]}
])
```
```
--------------------------------
### Creating Non-Standard HTML Attributes
Source: https://github.com/reagent-project/reagent/blob/master/doc/UsingHiccupToDescribeHTML.md
Shows how to define custom HTML attributes that are not standard keywords by using string keys in the attribute map. This allows for flexibility with non-standard attributes.
```clojure
[:span {"custom-attribute" "value"}]
```
--------------------------------
### Child Component: greet-number
Source: https://github.com/reagent-project/reagent/blob/master/doc/WhenDoComponentsUpdate.md
A simple child component that displays a greeting with a number. It expects an integer as a prop.
```clojure
(defn greet-number
"I say hello to an integer"
[num] ;; an integer
[:div (str "Hello #" num)])
```
--------------------------------
### Create Reagent Component Class with `create-class`
Source: https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md
Use `r/create-class` to define Reagent components that require custom methods or properties, ensuring compatibility when passed as classes to other React components. Avoid `r/reactify-component` for functions that return classes to maintain correct class recognition.
```clojure
;; Correct way
(def editor
(r/create-class
{:get-input-node (fn [this] ...)
:reagent-render (fn [] [:input ...])}))
[:> SomeComponent
{:editor-component editor}]
```
```clojure
;; Often incorrect way
(defn editor [parameter]
(r/create-class
{:get-input-node (fn [this] ...)
:reagent-render (fn [] [:input ...])}))
[:> SomeComponent
{:editor-component (r/reactify-component editor)}]
```
--------------------------------
### Run Figwheel Tests
Source: https://github.com/reagent-project/reagent/blob/master/doc/development.md
Use Figwheel to run tests in the browser during development. Open http://0.0.0.0:3449 and check the console for output.
```clojure
lein figwheel client # For Cljsjs
```
```clojure
lein figwheel client-npm # NPM
```
--------------------------------
### CSS Custom Properties Syntax for Style
Source: https://github.com/reagent-project/reagent/blob/master/doc/UsingHiccupToDescribeHTML.md
Demonstrates how to set CSS custom properties within the 'style' attribute by using a string key for the custom property name in the style map. This is a workaround due to keyword-to-property name conversion.
```clojure
[:span {:style {"--custom-property" "value"}}]
```
--------------------------------
### Create and Use a Reagent Atom
Source: https://github.com/reagent-project/reagent/blob/master/doc/ManagingState.md
Define a Reagent atom using `r/atom` and use it within a component. Components that dereference the atom will re-render when its value changes.
```clojure
(ns example
(:require [reagent.core :as r]))
(def click-count (r/atom 0))
(defn counting-component []
[:div
"The atom " [:code "click-count"] " has value: "
@click-count ". "
[:input {:type "button" :value "Click me!"
:on-click #(swap! click-count inc)}]])
```
--------------------------------
### Handle Function-as-child React Components in Reagent
Source: https://github.com/reagent-project/reagent/blob/master/doc/InteropWithReact.md
Shows how to pass a function as a child to React components that expect this pattern, using `reagent/adapt-react-class` and `reagent/as-element` for components like React AutoSizer.
```clojure
[(reagent/adapt-react-class AutoSizer)
{}
(fn [dims]
(let [dims (js->clj dims :keywordize-keys true)]
(reagent/as-element [my-component (:height dims)])))]
```
--------------------------------
### Using Parentheses: Function Call and Return Value
Source: https://github.com/reagent-project/reagent/blob/master/doc/UsingSquareBracketsInsteadOfParens.md
When a function like `greet` is called using parentheses (), it executes and returns a hiccup vector. This return value is then inserted into the parent structure.
```clojurescript
(greet "You")
;; => [:div "Hello " "You"] ;; a vector of a keyword and two strings
```
```clojurescript
(first (greet "You"))
;; => :div
```
```clojurescript
(second (greet "You"))
;; => "Hello"
```
--------------------------------
### Implement Suspense with Fallback Element
Source: https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md
Use `r/as-element` to provide a fallback UI for suspended components, similar to React's `Suspense`. This is useful for components from JavaScript libraries that utilize suspending.
```clojure
(def data #js {:current nil})
(def slow-data-request (js/Promise. (fn [resolve _reject] (js/setTimeout (fn [] (set! (.-current data) "ready!") (resolve)) 2000))))
(defn slow-component []
(when (nil? (.-current data))
;; React 18, in 19 react/use replaces throwing Promises to suspend
;; an component.
(throw slow-data-request))
[:div (.-current data)])
(defn simple-component []
[:div
[:> react/Suspense
{:fallback (r/as-element [:div "loading"])}
[slow-component]]])
```
--------------------------------
### Handle Events with rswap!
Source: https://github.com/reagent-project/reagent/blob/master/doc/ManagingState.md
Use `rswap!` for event handling, as it always returns `nil` and allows recursive calls, preventing potential issues with React's event handling.
```clojure
(defn event-handler [state [event-name id value]]
(case event-name
:set-name (assoc-in state [:people id :name] value)
:add-person (let [new-key (->> state :people keys (apply max) inc)]
(assoc-in state [:people new-key] {:name ""}))
state))
```
```clojure
(defn emit [e]
;; (js/console.log "Handling event" (str e))
(r/rswap! app-state event-handler e))
```
```clojure
(defn name-edit [id]
(let [p @(r/track person id)]
[:div
[:input {:value (:name p)
:on-change #(emit [:set-name id (.. % -target -value)])}]]))
```
```clojure
(defn edit-fields []
(let [ids @(r/track person-keys)]
[:div
[name-list]
(for [i ids]
^{:key i} [name-edit i])
[:input {:type 'button
:value "Add person"
:on-click #(emit [:add-person])}]))
```