GithubHelp home page GithubHelp logo

davidalphafox / uix Goto Github PK

View Code? Open in Web Editor NEW

This project forked from roman01la/uix

0.0 1.0 0.0 4.59 MB

Idiomatic ClojureScript interface to modern React.js

Home Page: https://roman01la.gitbook.io/uix/

License: Eclipse Public License 2.0

Shell 0.28% JavaScript 0.61% Clojure 36.48% HTML 62.63%

uix's Introduction

SWUbanner

Idiomatic ClojureScript interface to modern React.js

Discuss at #uix on Clojurians Slack. Bug reports, feature requests and PRs are welcome.

Try it in online REPL

Docs and Guides

API Documentation

CircleCI

Clojars updates are pushed occasionally, depend via Git deps to get the most recent updates.

Clojars Project Clojars Project Clojars Project

{:deps {uix.core {:git/url "https://github.com/roman01la/uix.git"
                  :deps/root "core"
                  :sha "{{replace with commit hash}}"}
        uix.dom {:git/url "https://github.com/roman01la/uix.git"
                 :deps/root "dom"
                 :sha "{{replace with commit hash}}"}
        uix.rn {:git/url "https://github.com/roman01la/uix.git"
                :deps/root "rn"
                :sha "{{replace with commit hash}}"}}}
(require '[uix.core.alpha :as uix])
(require '[uix.dom.alpha :as uix.dom])

(defn button [{:keys [on-click]} text]
  [:button.btn {:on-click on-click}
    text])

(defn app []
  (let [state* (uix/state 0)]
    [:<>
      [button {:on-click #(swap! state* dec)} "-"]
      [:span @state*]
      [button {:on-click #(swap! state* inc)} "+"]]))

(uix.dom/render [app] js/root)

Recipes

Features

Hiccup syntax extension

  • [:div#id.class] or [:#id.class]
  • [:> js/Component attrs & children] - interop with JS components
  • [:<> attrs & children] - React.Fragment
  • [:# {:fallback element} & children] - React.Suspense

Hooks

React Hooks in idiomatic Clojure style

;; state hook
;; (mutable ref type, re-renders component when mutated)
(let [state (uix/state 0)]
  (swap! state inc)
  @state) ; 1

;; ref hook
;; (mutable ref type, doesn't cause re-renders)
(let [ref (uix/ref 0)]
  (swap! ref inc)
  @ref) ; 1

;; effect hook
(uix/effect!
  (fn []
    (prn "after update")
    #(prn "before unmount"))
  [deps])

;; convenience macro for uix.core/effect!
(uix/with-effect [deps]
  (prn "after update")
  #(prn "before unmount"))

;; more in uix.core.alpha ns

Attributes syntax extension

Injects provided function into attributes transformation stage. Could be used for various side effects, such as processing styles with CSS-in-JS libraries (see uix.recipes.dynamic-styles).

(uix.core.alpha/add-transform-fn
  (fn [attrs]
    (my-transform-attrs attrs)))

Hiccup pre-compilation (advanced)

NOTE: UIx interpreter is already super fast (3x faster than Reagent and only 2x slower than vanilla React). Use pre-compilation ONLY if you are hitting performance problems.

Compiles Hiccup into inlined React elements at compile-time and hoists constant elements so they can be shared across components in different namespaces (for reference see @babel/plugin-transform-react-inline-elements and @babel/plugin-transform-react-constant-elements). Hoisting is enabled with :optimize-constants compiler option, which is automatically enabled for :optimizations :advanced.

(uix/html
  [:h1 "Title"])

;; emits this
{
  $$typeof: Symbol.for("react.element"),
  key: null,
  ref: null,
  props: { children: "Title" },
  _owner: null
}

Lazy loading components

Loading React components on-demand as Closure modules. See code splitting guide and how lazy loading is used in React with Suspense: guide.

(uix.core.lazy-loader/require-lazy
  '[uix.components :refer [ui-list]])

[:# {:fallback "Loading..."}
  (when show?
    [ui-list])]

Server-side rendering

UIx can be used for SSR or usual templating in both JVM and JavaScript runtimes

Server-side rendering in JVM

See an example in uix.recipes.server-rendering

(uix.dom/render-to-string element) ;; see https://reactjs.org/docs/react-dom-server.html#rendertostring
(uix.dom/render-to-static-markup element) ;; see https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup

;; Streaming HTML
(uix.dom/render-to-stream element {:on-chunk f}) ;; see https://reactjs.org/docs/react-dom-server.html#rendertonodestream
(uix.dom/render-to-static-stream element {:on-chunk f}) ;; see https://reactjs.org/docs/react-dom-server.html#rendertostaticnodestream

Server-side rendering in JS

SSR works in JavaScript environment via React's serializer using same API.

  1. Add ReactDOMServer into your dependencies (as cljsjs/react-dom-server or any other way)
  2. Run (uix.dom/render-to-string element)

Benchmarks

  • Hiccup interpretation clojure -A:dev:benchmark:bench-front
  • SSR on JVM clojure -A:dev:benchmark:bench-ssr

Hiccup interpretation

react x 23866 ops/s, elapsed 419ms
uix-interpret x 11848 ops/s, elapsed 844ms
reagent-interpret x 4031 ops/s, elapsed 2481ms

SSR on JVM

lib test 1 test 2 test 3
rum 107.8 µs 3.6 ms 7.7 ms
uix 120.8 µs 3.8 ms 8.1 ms
uix streaming 115.7 µs 3.4 ms 7.6 ms
hiccup 205.7 µs 6.5 ms 16.6 ms

TodoMVC bundle size

lib size gzip
rum 254KB 70KB
reagent 269KB 74KB
uix 234KB 65KB

Figwheel

When developing with Figwheel it is recommended to mark root render function with ^:after-load meta, so Figwheel can update UI tree once the code was re-evaluated.

(ns ^:figwheel-hooks my.ns)

(defn ^:after-load render []
  (uix.dom/render [app] js/root))

React DevTools

When inspecting UI tree in React DevTools, filter out memo components to get cleaner view of components tree.

Testing

scripts/test

Note: to ensure you're using the right Node.js version, you can use nvm and run nvm use once in the directory. Otherwise the Node.js version you use is in the .nvmrc file. See nvm repo for more documentation.

Who’s using UIx

uix's People

Contributors

abcdw avatar caleb avatar codeasone avatar crofty avatar darwin avatar den1k avatar djebbz avatar galdolber avatar jimmyhmiller avatar mhuebert avatar nwjsmith avatar olimsaidov avatar roman01la avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.