c o n t e n t s


🏃🏽‍♀️ Example

Here’s an example of useState and useEffect from the React docs:

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Here’s the same thing in Reagent:

(ns use-hooks.example
  (:require [react :as react]))

(defn example* []
  (let [[count set-count] (react/useState 0)]
    (react/useEffect
	   (fn []
       (set! (.-title js/document) (str "You clicked " count " times")))
	   #js [count]) ;; <- Array of dependencies that trigger the effect
                     ;; Make sure it's a JavaScript array!
    [:div
     [:p "You clicked " count " times"]
     [:button {:on-click #(set-count (inc count))}
      "Click me"]]))

(defn example []
  [:f> example*])

:f> is a shortcut that creates function components from Reagent components, where both hooks and atoms work!

You can use all hooks this way, not just the ones shown here. That includes custom hooks and those from external libraries, which are increasingly adopting hooks for their simplicity and ease of use.

🚲 Why this way?

By default, Reagent takes ClojureScript functions in Hiccup vectors and turns them into React Class components. If you want to use hooks though, you need functional components. How do we make those in Reagent?

When you wrap a function in :f>, instead of the default Reagent→class component treatment, it’s wrapped inside another function that uses two state hooks to store 1) component identity and 2) an “update count.” This is used to force re-render when atoms are updated.

Check out this Reagent doc for the full story on functions as components, including other methods like create-element, as-element, and adapt-react-class.

🌊 The new way

According to Github history, :f> arrived quietly to Reagent sometime in May 2020. I never came across anyone using it or hooks in general, so I thought it wasn't an option. When I finally discovered this buried in the docs, I was so excited...that I didn’t even notice the real gem, casually inserted at the end:

”New way is to configure Reagent Hiccup-compiler to create functional components: Read Compiler documentation”

You can configure the Reagent compiler to automatically create Functional components instead of Class components!