Coder Social home page Coder Social logo

darwin / uix Goto Github PK

View Code? Open in Web Editor NEW

This project forked from roman01la/uix

0.0 2.0 0.0 3.29 MB

Idiomatic ClojureScript interface to modern React.js

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

License: Eclipse Public License 2.0

Clojure 35.11% HTML 64.15% JavaScript 0.60% Shell 0.14%

uix's Introduction

Idiomatic ClojureScript interface to modern React.js

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

Try it live

API Documentation

CircleCI

There are no versioned releases yet, use deps.edn to depend on the code via git deps.

{: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/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

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.