Skip to content

Reagent Tutorial

David Nolen edited this page Sep 13, 2023 · 44 revisions

Create A React Native App

Follow the instructions for creating a React Native development environment. Make sure you follow the steps in the React Native CLI Quickstart tab, not Expo. Those instructions are not replicated here as React Native changes with relative frequency.

Krell does not provide a facade over the React Native CLI. This separation not only simplifies the implementation but ensures that React Native upgrades require no additional instructions beyond the official documentation.

Once you've verified that your React Native development environment works in either iOS or Android you can continue with this tutorial.

Requirements

Make sure you have the following dependencies installed on your machine:

Setting up ClojureScript

In your AwesomeProject directory create a deps.edn file with the following contents:

{:deps {io.vouch/krell {:git/url "https://github.com/vouch-opensource/krell.git"
                        :sha "08f2bfea96aa48feb8511851e37f5948453986e5"}
        io.vouch/reagent-react-native {:git/url "https://github.com/vouch-opensource/reagent-react-native.git"
                                       :sha "dc4a6730e0da3f8b99243b1fd0912a5c802b43bc"}
        reagent/reagent {:mvn/version "1.2.0"
                         :exclusions [cljsjs/react cljsjs/react-dom]}}}

If you have dependency defaults defined in ~/.clojure/deps.edn make sure to add the -Srepro flag to your clj commands.

Install the Node.js dependencies required for the Krell REPL:

clj -M -m cljs.main --install-deps

This will take a while. If it fails due to JS resolution problems (likely on NPM 7) then delete node_modules and try yarn:

yarn install
clj -M -m cljs.main -co "{:deps-cmd \"yarn\"}" --install-deps

iOS

Switch into the ios directory of your React Native project and install the pods:

cd ios
pod install

Write some ClojureScript

Create src/awesome_project/core.cljs with following contents:

(ns awesome-project.core
  (:require [reagent.core :as r]
            [reagent.react-native :as rn]))

(defn hello []
  [rn/view {:style {:flex 1 :align-items "center" :justify-content "center"}}
   [rn/text {:style {:font-size 50}} "Hello Krell!"]])

(defn ^:export -main [& args]
  (r/as-element [hello]))

It's important that -main more or less looks like the above in order for Reagent to detect changes. You can have whatever expressions in the body of -main that you like, but the last form must be an as-element call with your entry-point function inside of a Hiccup literal.

Developing with Krell

Create a build.edn file with the following contents:

{:main awesome-project.core
 :output-to "target/main.js"
 :output-dir "target"}

Run a dev build and launch a REPL:

clj -M -m krell.main -co build.edn -c -r

Make sure that you write krell.main not cljs.main.

You should see a prompt saying that Krell is waiting for suitable device top connect.

Using the REPL

Build the React Native app for the simulator or device. There are many ways to do this but if you'd like to copy and paste the command for iOS is:

npx react-native start
npx react-native run-ios

For Android:

npx react-native start
npx react-native run-android

If the above commands fail, please read over the React Native docs linked to at the beginning of this tutorial.

The REPL will connect to the running app and begin loading files. Once that completes, you should see your UI. Try some typical expressions at the REPL!

Hot Reloading

Try changing some of the styles on the main component. You should see these changes reflected in the simulator or device. Try making some changes to intentionally trigger ClojureScript compiler warnings:

(defn foo []
  (+ a b)) ;; foo doesn't take a & b as parameters

Or to cause an exception:

(defn foo [] ;; missing closing parens

You should see a warning in the running React application.

That's it! If you run into a problem or are interested in an enhancement please file a GitHub issue. If you'd like to discuss the project in realtime then jump on the #cljsrn Clojurians Slack channel

Production build

Just add -O advanced to the usual build command:

clj -M -m krell.main -v -co build.edn -O advanced -c

And re-run your app. If you see a weird message about npm_deps.js you may need to restart Metro.