React ,redux core idea

in

clojurescript

link: slides.com/vehas/re-in-cljs

React ,redux core idea

in

clojurescript

bio

~ 1 yr with react native, redux

~ 1 yr with clojure, clojurescript

Fb.com/vehas

Github.com/vehas

https://clojureverse.org/u/vehas

clojurescript

  1. Simplicity
  2. data - oriented

one syntax, data-oriented

(fn op1 op2)

3 lisp

4 dynamic type

5  functional programming

6 compiled to js (browser, node)

clojurescript vs javascript

  javascript   meaning   clojurescript
const  ten = 10; defined variable ten
add(10, 1) call function (add 10 1)
[1, 2, 3].map(inc) map array, vector (map inc [1 2 3])
function inc(n){
 return n+1
}
defined function (defn inc [n]
    n)
(def ten 10 )
(add 10 1)
(map inc [1 2 3])
(defn inc [n]
  (+ n 1) )

clojurescript core idea

data driven

 

 

1
20.1
:key
:module-a/key
'symbol
"string"
( 1 2 3 4 )  ;list
[1 2 3 4]   ;vector
{1 2, 3 4 } ;hash-map: 
(def ten 10) ;list (as code)
(defn error [message]
   {:error message})

clojurescript core idea

pure function

(defn inc [n]
  (+ n 1))
(range 6 )          ; (1 2 3 4 5 6)
(map inc (range 6)) ; (2 3 4 5 6 7)
(filter odd? (range 6)))  ; (2 4 6)
(reduce + (range 6))      ; 21

(->> (range 6)     ; (1 2 3 4 5 6)
     (map inc)     ; (2 3 4 5 6 7)
     (filter odd?) ; (2 5 7)
     (reduce +))   ; 14

clojurescript core idea

  1. data flow
  2. performance
  3. equality check 
  4. react re-render performance
  5. transience

immutable data 

clojurescript core idea

;; Clojure code
(ns my.namespace)

;; print using JS console
(def obj #js{:k "bar"}) ;; var obj = {k: 'bar'}
(.log js/console obj)   ;; console.log(obj)
;; => {foo: 'bar'}

;; JS-callable function
(defn ^:export add [a b] ;;function add = (a, b){ 
  (+ a b))               ;;  return a + b
                         ;;}
// JS code
my.namespace.add(7, 11);
// => 18

reagent

=

react  × clojurescript × data-oriented

react 

 

 

data  Juggling

core idea

state come form

somewhere else

reagent 

component life cycle

reactive  state by 

atom

state, prop

data driven

jsx

view

reactive state

data  Juggling

react 

jsx

 

 

view

core idea

<div>
   <h1>jsx</h1>
</div>

data structure

reagent 

[:div
 [:h1 "jsx"]]
<ul> 
{[1,2,3]
 .map(n =>
   <li>n</li>)}
</ul>
[:ul
  (->> [1 2 3]
    (map
     (fn [n]
      [:li n]))]]

react 

state, prop

 

 

reactive state

core idea

class BigJsx extends Component {
  constructor(props) {
    super(props);
    this.state = {
      jsx: 1
    };
  }
  render() {
    return (<div>
      <h1>
        jsx: {this.state.jsx}
      </h1> 
    </div >)
  }
}

reactive state

reagent 

(def jsx (atom 0))

(defn big-jsx []
 [:div
  [:h2 "jsx"
       @jsx]])

react 

state, prop

reactive state

core idea

class BigJsx extends Component {
  state = {jsx: 1};
  click = _=>
    this.setState({
      jsx: this.state.jsx + 1
    })
  render() {
    return (
     <div
      onClick={this.click}>
      <h1>jsx:
       {this.state.jsx}
      </h1> 
     </div>)
  }
}

reactive state

reagent 

(def jsx (atom 0))

(defn big-jsx []
 [:div
  {:on-click
   (fn []
    (swap! jsx inc))}
  [:h2 "jsx"
       @jsx]])

react 

 

 

data  Juggling

core idea

class BigJsx extends
  React.Component {
  state = {jsx: 1};
componentDidMount() {
 // call server
}
  render() {
    return (
     <div
      onClick={this.click}>
      <h1>jsx:
    {this.prop.jsx}
      </h1> 
     </div>)}}

state come form

somewhere else

reagent 

(def jsx (atom 0))

(defn big-jsx []
 [:div
  [:h2 "jsx"
       @some-atom]])

component life cycle

redux core idea

redux implementation

re-frame

=

redux  × clojurescript  +  subscription

re-frame

Real-world.io project (First meaningful paint)

Real-world.io project (Size)

Real-world.io project (line  of code)

1 user interaction with ui

2 dispatch action

3 call event (reducer)

4 update  store

5 subscription query store

6 reactive view base 

   on subscription atom

re-frame  flow

1 user interaction with ui

2 dispatch action

3 call event (reducer)

4 update  store

5 subscription query store

6 reactive view base 

   on subscription atom

re-frame  flow

(defn delete-button 
  [item-id]
  [:div.garbage-bin 
     {:on-click
      #(re-frame.core/dispatch
         [:del/delete-item item-id]})])

1 user interaction with ui

2 dispatch action

3 call event (reducer)

4 update  store

5 subscription query store

6 reactive view base 

   on subscription atom

re-frame  flow

(re-frame.core/reg-event-fx   ;; re-frame API
  :delete-item                ;; the kind of event
  delete-item)                ;; the handler function 

(defn delete-item                
 [coeffects event]              ;; `coeffects` holds db
 (let [item-id (second event)   ;; extract id 
       db      (:db coeffects)] ;; extract db
   {:db  (dissoc-in db [:items item-id])})) ;;change db

1 user interaction with ui

2 dispatch action

3 call event (reducer)

4 update  store

5 subscription query store

6 reactive view base 

   on subscription atom

re-frame  flow

(re-frame.core/reg-sub   ;; part of the re-frame API
   ::query-items         ;; query id  
   query-fn)             ;; query fn

(defn query-fn
  [db v]         ;; v the query vector
  (:items db))   ;; not much of a materialised view

1 user interaction with ui

2 dispatch action

3 call event (reducer)

4 update  store

5 subscription query store

6 reactive view base

   on subscription atom

re-frame  flow

(defn items-view
  []
  (let [items  (subscribe
                 [:query/query-items])] ;; sub item
    [:ul (map (fn [item]
                 [:li item]))
              @items)]))      

re-frame with side effect

declarative  server call by re-frame-http-fx

(re-frame.core/reg-event-fx  ;; note the trailing -fx
  :handler-with-http         ;; usage:  (dispatch [:handler-with-http])
  (fn [{:keys [db]} _]                    ;; the first param contain DB
    {:db   (assoc db :show-twirly true)   ;; show loading
     :http-xhrio {:method          :get
                  :uri             "https://example.com"
                  :on-success      [::good-http-result]
                  :on-failure      [::bad-http-result]}}))
(re-frame.core/reg-event-db
  ::good-http-result
  (fn [db [_ result]]
    (assoc db :api-result result)))

call another action when success

superpower re-frame dev tool

insert  smart quote from alan key 

insert dev tool 

https://jacekschae.github.io/conduit-re-frame-10x-demo/#/@werner123/favorites

re-frame template

lein new re-frame  {app-name}

                  +10x

                  +test 

                 + handler 

back to javascript world 

 clojurescript js 
functional utility Ramda.js
namespace action reduxsauce
immutable data immutable.js
re-frame subscription flow re-select, re-compose
data driven view babel-plugin-transform-react-pug

learn  clojurescript

Thai clojure group

     fb.com/groups/clojurethai

learning

     tons of resource in Thai, just google : "เริ่ม clojure"

     tons of clj, cljs book, link, video in english

job

     we're hiring  !!! 

we're hiring  !!!

some well design library from clojure

clojure.spec complete type validation,  generative testing, document
core.async go style SCP
datascript relational, graph database in browser
specter language for complex  data transformation

key takeaway

learn new language is like get a new lens, 

you will looking at the same thing  in the different, more creative way.

clojure, clojurescript are one of the most fantasy lens.

link:   slides.com/vehas/re-in-cljs

React, Redux’ s core idea with Clojurescript

By Veha Suwatphisankij

React, Redux’ s core idea with Clojurescript

เราจะนำ React, Redux ไปเทียบกับสิ่งที่คล้ายกันบนภาษา clojurescript ศึกษา, เรียนรู้, ลองใช้, และนำแนวคิดต่าง ๆ กลับไปใช้บน js หรือคุณอาจไม่อยากกลับไปอีกเลย

  • 488