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
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
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