Essential Chrome extension for development:
Enable in Chrome DevTools settings:
mkdir app && cd app
mkdir -p src/main src/dev resources/public
npm init
npm install shadow-cljs react react-dom --save
deps.edn
){:paths ["src/main" "resources"]
:deps {org.clojure/clojure {:mvn/version "1.10.3"}
com.fulcrologic/fulcro {:mvn/version "3.5.9"}}
:aliases {:dev {:extra-paths ["src/dev"]
:extra-deps {org.clojure/clojurescript {:mvn/version "1.10.914"}
thheller/shadow-cljs {:mvn/version "2.16.9"}
binaryage/devtools {:mvn/version "1.0.4"}}}}}
shadow-cljs.edn
){:deps {:aliases [:dev]}
:dev-http {8000 "classpath:public"}
:builds {:main {:target :browser
:output-dir "resources/public/js/main"
:asset-path "/js/main"
:modules {:main {:init-fn app.client/init
:entries [app.client]}}
:devtools {:after-load app.client/refresh
:preloads [com.fulcrologic.fulcro.inspect.preload]}}}}
resources/public/index.html
)<html>
<meta charset="utf-8">
<body>
<div id="app"></div>
<script src="/js/main/main.js"></script>
</body>
</html>
src/main/app/application.cljs
)(ns app.application
(:require [com.fulcrologic.fulcro.application :as app]))
(defonce app (app/fulcro-app))
src/main/app/ui.cljs
)(ns app.ui
(:require
[com.fulcrologic.fulcro.components :as comp :refer [defsc]]
[com.fulcrologic.fulcro.dom :as dom]))
(defsc Person [this {:person/keys [name age]}]
(dom/div
(dom/p "Name: " name)
(dom/p "Age: " age)))
(def ui-person (comp/factory Person))
(defsc Root [this props]
(dom/div
(ui-person {:person/name "Joe" :person/age 22})))
src/main/app/client.cljs
)(ns app.client
(:require
[app.application :refer [app]]
[app.ui :as ui]
[com.fulcrologic.fulcro.application :as app]))
(defn ^:export init []
(app/mount! app ui/Root "app"))
(defn ^:export refresh []
(app/mount! app ui/Root "app"))
npx shadow-cljs server
;; Connect to nREPL and select build
user=> (shadow/repl :main)
;; Test connection
cljs.user=> (js/alert "Hi")
(defsc ComponentName [this props]
{:query [...] :ident [...] :initial-state {...}} ; optional
(dom/div {:className "a" :style {:color "red"}}
(dom/p "Hello")))
;; Various syntax forms
(dom/div {:id "id" :className "x y z"} ...)
(dom/div :.x#id {:className "y z"} ...)
(dom/div :.x.y.z#id ...)
(dom/div :.x#id {:classes ["y" "z"]} ...)
(def ui-person (comp/factory Person {:keyfn :person/id}))
;; Usage
(ui-person {:person/name "Joe" :person/age 22})
(defsc Person [this {:person/keys [name age]}]
{:initial-state (fn [{:keys [name age]}] {:person/name name :person/age age})}
(dom/div ...))
(defsc Root [this {:keys [friends enemies]}]
{:initial-state (fn [_] {:friends (comp/get-initial-state Person {:name "Joe" :age 22})})
(dom/div (ui-person friends)))
(defsc Person [this {:person/keys [name age]}]
{:query [:person/name :person/age]
:initial-state ...}
(dom/div ...))
(defsc Root [this {:keys [friends]}]
{:query [{:friends (comp/get-query Person)}]}
(dom/div (ui-person friends)))
Incorrect:
(ui-person (assoc props :onDelete delete-fn)) ; Lost on refresh
Correct:
(defsc Person [this {:person/keys [name]} {:keys [onDelete]}] ; computed props
(dom/div (dom/button {:onClick #(onDelete name)} "Delete")))
;; Parent passes computed props
(ui-person (comp/computed person-data {:onDelete delete-fn}))
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
Ctrl+k | Jump to recent docs |
← | Move to previous article |
→ | Move to next article |
Ctrl+/ | Jump to the search field |