mirror of https://github.com/status-im/reagent.git
Describe new features since first alpha in news050.cljs
This commit is contained in:
parent
60c074b633
commit
d4a595e577
|
@ -7,11 +7,22 @@
|
||||||
[reagentdemo.common :as common :refer [demo-component]]))
|
[reagentdemo.common :as common :refer [demo-component]]))
|
||||||
|
|
||||||
(def url "news/news050.html")
|
(def url "news/news050.html")
|
||||||
(def title "News in 0.5.0-alpha")
|
(def title "News in 0.5.0")
|
||||||
|
|
||||||
|
(def new-in-alpha [:strong "New since 0.5.0-alpha: "])
|
||||||
|
|
||||||
(def ns-src (s/syntaxed "(ns example
|
(def ns-src (s/syntaxed "(ns example
|
||||||
(:require [reagent.core :as r :refer [atom]]))"))
|
(:require [reagent.core :as r :refer [atom]]))"))
|
||||||
|
|
||||||
|
(def cel-link "http://facebook.github.io/react/docs/top-level-api.html#react.createelement")
|
||||||
|
|
||||||
|
(def figwheel-link "https://github.com/bhauman/lein-figwheel")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(defonce person (atom {:name
|
||||||
|
{:first-name "John" :last-name "Smith"}}))
|
||||||
|
|
||||||
(defn input [prompt val]
|
(defn input [prompt val]
|
||||||
[:div
|
[:div
|
||||||
prompt
|
prompt
|
||||||
|
@ -28,15 +39,33 @@
|
||||||
[input "Last name: " (r/wrap last-name
|
[input "Last name: " (r/wrap last-name
|
||||||
swap! n assoc :last-name)]]))
|
swap! n assoc :last-name)]]))
|
||||||
|
|
||||||
(defonce person (atom {:name
|
|
||||||
{:first-name "John" :last-name "Smith"}}))
|
|
||||||
|
|
||||||
(defn parent []
|
(defn parent []
|
||||||
[:div
|
[:div
|
||||||
[:p "Current state: " (pr-str @person)]
|
[:p "Current state: " (pr-str @person)]
|
||||||
[name-edit (r/wrap (:name @person)
|
[name-edit (r/wrap (:name @person)
|
||||||
swap! person assoc :name)]])
|
swap! person assoc :name)]])
|
||||||
|
|
||||||
|
(defn cursor-name-edit [n]
|
||||||
|
(let [{:keys [first-name last-name]} @n]
|
||||||
|
[:div
|
||||||
|
[:p "I'm editing " first-name " " last-name "."]
|
||||||
|
|
||||||
|
[input "First name: " (r/cursor n [:first-name])]
|
||||||
|
[input "Last name: " (r/cursor n [:last-name])]]))
|
||||||
|
|
||||||
|
(defn cursor-parent []
|
||||||
|
[:div
|
||||||
|
[:p "Current state: " (pr-str @person)]
|
||||||
|
[cursor-name-edit (r/cursor person [:name])]])
|
||||||
|
|
||||||
|
(defn person-get-set
|
||||||
|
([k] (get-in @person k))
|
||||||
|
([k v] (swap! person assoc-in k v)))
|
||||||
|
|
||||||
|
(defn get-set-parent []
|
||||||
|
[:div
|
||||||
|
[:p "Current state: " (pr-str @person)]
|
||||||
|
[cursor-name-edit (r/cursor person-get-set [:name])]])
|
||||||
|
|
||||||
(defn integration []
|
(defn integration []
|
||||||
[:div
|
[:div
|
||||||
|
@ -58,21 +87,59 @@
|
||||||
#js{}
|
#js{}
|
||||||
"world")]])
|
"world")]])
|
||||||
|
|
||||||
(def cel-link "http://facebook.github.io/react/docs/top-level-api.html#react.createelement")
|
|
||||||
|
|
||||||
(def figwheel-link "https://github.com/bhauman/lein-figwheel")
|
(def div-adapter (r/adapt-react-class "div"))
|
||||||
|
|
||||||
|
(defn adapted []
|
||||||
|
[div-adapter {:class "foo"}
|
||||||
|
"Hello " [:strong "world"]])
|
||||||
|
|
||||||
|
|
||||||
|
(defn exported [props]
|
||||||
|
[:div "Hi, " (:name props)])
|
||||||
|
|
||||||
|
(def react-comp (r/reactify-component exported))
|
||||||
|
|
||||||
|
(defn could-be-jsx []
|
||||||
|
(r/create-element react-comp #js{:name "world"}))
|
||||||
|
|
||||||
|
|
||||||
(defn main [{:keys [summary]}]
|
(defn main [{:keys [summary]}]
|
||||||
[:div.reagent-demo
|
[:div.reagent-demo
|
||||||
[:h1 [link {:href url} title]]
|
[:h1 [link {:href url} title]]
|
||||||
[:div.demo-text
|
[:div.demo-text
|
||||||
[:p "Lots of new features (and one breaking change) in Reagent
|
[:p "Reagent 0.5.0 has automatic importing of React.js, two kinds
|
||||||
0.5.0-alpha."]
|
of cursors, better integration of native React components, better
|
||||||
|
performance, easier integration with e.g Figwheel, and more."]
|
||||||
|
|
||||||
(if summary
|
(if summary
|
||||||
[link {:href url
|
[link {:href url
|
||||||
:class 'news-read-more} "Read more"]
|
:class 'news-read-more} "Read more"]
|
||||||
[:div.demo-text
|
[:div.demo-text
|
||||||
|
[:h2 "A new way of importing React"]
|
||||||
|
|
||||||
|
[:p new-in-alpha "Reagent now takes advantage of
|
||||||
|
ClojureScript’s new way of packaging JavaScript dependencies.
|
||||||
|
That means that you no longer have to include React in your
|
||||||
|
HTML, nor should you use " [:code ":preamble"] ". Instead,
|
||||||
|
Reagent depends on the " [:code "cljsjs/react"] " library."]
|
||||||
|
|
||||||
|
[:p "If you want to use another version of React, you can do
|
||||||
|
that in two ways. In both cases you’ll have to
|
||||||
|
exclude " [:code "cljsjs/react"] " by using
|
||||||
|
e.g " [:code "[reagent \"0.5.0-alpha3\" :exclusions [cljsjs/react]]"]
|
||||||
|
" in the " [:code ":dependencies"] " section of your "
|
||||||
|
[:code "project.clj"] "."]
|
||||||
|
|
||||||
|
[:p "You can then add e.g " [:code "[cljsjs/react-with-addons
|
||||||
|
\"0.12.2-4\"]"] " as a dependency. Or you can add a file
|
||||||
|
named " [:code "cljsjs/react.cljs"] ", containing
|
||||||
|
just " [:code "(ns cljsjs.react)"] ", to your project – and then
|
||||||
|
import React in some other way."]
|
||||||
|
|
||||||
|
[:p "Reagent now requires ClojureScript 0.0-2816 or later."]
|
||||||
|
|
||||||
|
|
||||||
[:h2 "Splitting atoms"]
|
[:h2 "Splitting atoms"]
|
||||||
|
|
||||||
[:p "Reagent now has a simple way to make reusable components
|
[:p "Reagent now has a simple way to make reusable components
|
||||||
|
@ -95,8 +162,8 @@
|
||||||
|
|
||||||
[demo-component {:comp parent
|
[demo-component {:comp parent
|
||||||
:src [:pre ns-src
|
:src [:pre ns-src
|
||||||
(s/src-of [:input :name-edit
|
(s/src-of [:person :input :name-edit
|
||||||
:person :parent])]}]
|
:parent])]}]
|
||||||
|
|
||||||
[:p "Here, the " [:code "parent"] " component controls the
|
[:p "Here, the " [:code "parent"] " component controls the
|
||||||
global state, and delegates editing the name
|
global state, and delegates editing the name
|
||||||
|
@ -112,6 +179,60 @@
|
||||||
and that the callback function in the end must cause a ”real”
|
and that the callback function in the end must cause a ”real”
|
||||||
atom to change."]
|
atom to change."]
|
||||||
|
|
||||||
|
[:h2 "Cursors"]
|
||||||
|
|
||||||
|
[:p new-in-alpha "Reagent has another way of isolating part of
|
||||||
|
a data structure in an atom: " [:code "reagent.core/cursor"] ".
|
||||||
|
Using the same state as in the previous example, usage now looks
|
||||||
|
like this:"]
|
||||||
|
|
||||||
|
[demo-component {:comp cursor-parent
|
||||||
|
:src (s/src-of [:cursor-name-edit
|
||||||
|
:cursor-parent])}]
|
||||||
|
|
||||||
|
[:p new-in-alpha "Cursors can now also be generalized to use
|
||||||
|
any transformation of data from and to a source atom (or many
|
||||||
|
atoms, for that matter). To use that, you pass a function
|
||||||
|
to " [:code "cursor"] " instead of an atom, as in this
|
||||||
|
example:"]
|
||||||
|
|
||||||
|
[demo-component {:comp cursor-parent
|
||||||
|
:src (s/src-of [:person-get-set
|
||||||
|
:get-set-parent])}]
|
||||||
|
|
||||||
|
[:p "The function passed to " [:code "cursor"] " will be called
|
||||||
|
with one argument to get data (it is passed the key, i.e the
|
||||||
|
second argument to " [:code "cursor"] "), and two arguments
|
||||||
|
when the cursor is changed (then it is passed the key and the
|
||||||
|
new value)."]
|
||||||
|
|
||||||
|
[:p "The getter function can reference one or many Reagent
|
||||||
|
atoms (or other cursors). If the cursor is used in a component
|
||||||
|
the getter function will re-run to change the value of the
|
||||||
|
cursor just like a Reagent component does."]
|
||||||
|
|
||||||
|
[:h3 "Values and references"]
|
||||||
|
|
||||||
|
[:p "So what’s the difference between wraps and cursors? Why
|
||||||
|
have both?"]
|
||||||
|
|
||||||
|
[:p "A " [:code "wrap"] " is just a value that happens to look
|
||||||
|
like an " [:code "atom"] ". It doesn’t change unless you tell
|
||||||
|
it to. It is a very lightweight combination of value and a
|
||||||
|
callback to back-propagate changes to the value. It relies only
|
||||||
|
on Reagent’s equality test
|
||||||
|
in " [:code ":should-component-update"] " to avoid unnecessary
|
||||||
|
re-rendering."]
|
||||||
|
|
||||||
|
[:p "A " [:code "cursor"] ", on the other hand, will always be
|
||||||
|
up-to-date with the value of the source atom. In other words,
|
||||||
|
it acts a reference to part of the value of the source.
|
||||||
|
Components that " [:code "deref"] " cursors are re-rendered
|
||||||
|
automatically, in exactly the same way as if
|
||||||
|
they " [:code "deref"] " a normal Reagent atom (unnecessary
|
||||||
|
re-rendering is avoided by checking if the cursor's value has
|
||||||
|
changed using " [:code "identical?"] ")."]
|
||||||
|
|
||||||
|
|
||||||
[:h2 "Faster rendering"]
|
[:h2 "Faster rendering"]
|
||||||
|
|
||||||
|
@ -149,6 +270,29 @@
|
||||||
[demo-component {:comp integration
|
[demo-component {:comp integration
|
||||||
:src (s/src-of [:integration])}]
|
:src (s/src-of [:integration])}]
|
||||||
|
|
||||||
|
[:p new-in-alpha "If you don't need/want this kind of low-level
|
||||||
|
control over interaction with javascript React, you can also
|
||||||
|
use the new function " [:code "adapt-react-class"] ", that will
|
||||||
|
take any React class, and turn it into something that can be
|
||||||
|
called from Reagent directly. The example from above would then
|
||||||
|
become:"]
|
||||||
|
|
||||||
|
[demo-component {:comp adapted
|
||||||
|
:src (s/src-of [:div-adapter :adapted])}]
|
||||||
|
|
||||||
|
[:p new-in-alpha "You can also do the opposite: call Reagent
|
||||||
|
components from JavaScript React (for example from JSX). For
|
||||||
|
this purpose, you'd use another adapter
|
||||||
|
– " [:code "reactify-component"] " – like this:"]
|
||||||
|
|
||||||
|
[demo-component {:comp could-be-jsx
|
||||||
|
:src (s/src-of [:exported :react-comp
|
||||||
|
:could-be-jsx])}]
|
||||||
|
|
||||||
|
[:p "The " [:code "exported"] " component will be called with a
|
||||||
|
single argument: the React " [:code "props"] ", converted to a
|
||||||
|
ClojureScript " [:code "map"] "."]
|
||||||
|
|
||||||
|
|
||||||
[:h2 "More equality"]
|
[:h2 "More equality"]
|
||||||
|
|
||||||
|
@ -165,13 +309,14 @@
|
||||||
|
|
||||||
[:h2 "React 0.12"]
|
[:h2 "React 0.12"]
|
||||||
|
|
||||||
[:p "Reagent now comes with, and requires, React 0.12.1. To
|
[:p "Reagent now comes with, and requires, React 0.12.2. To
|
||||||
mirror the changes in API in React, some Reagent functions have
|
mirror the changes in API in React, some Reagent functions have
|
||||||
gotten new names: "]
|
gotten new names: "]
|
||||||
|
|
||||||
[:ul
|
[:ul
|
||||||
[:li [:code "render-component"] " is now " [:code "render"]]
|
[:li [:code "render-component"] " is now " [:code "render"]]
|
||||||
[:li [:code "render-component-to-string"] " is now " [:code "render-to-string"]]
|
[:li [:code "render-component-to-string"] " is
|
||||||
|
now " [:code "render-to-string"]]
|
||||||
[:li [:code "as-component"] " is now " [:code "as-element"]]]
|
[:li [:code "as-component"] " is now " [:code "as-element"]]]
|
||||||
|
|
||||||
[:p "The old names still work, though."]
|
[:p "The old names still work, though."]
|
||||||
|
@ -188,6 +333,9 @@
|
||||||
e.g. the rather excellent " [:a {:href
|
e.g. the rather excellent " [:a {:href
|
||||||
figwheel-link} "figwheel"] ", since " [:code "render"] " now
|
figwheel-link} "figwheel"] ", since " [:code "render"] " now
|
||||||
will cause the entire component tree to update (by-passing the
|
will cause the entire component tree to update (by-passing the
|
||||||
equality checks)."] ])]])
|
equality checks)."]
|
||||||
|
|
||||||
|
[:p new-in-alpha "All the examples in the Reagent repo now uses
|
||||||
|
figwheel."]])]])
|
||||||
|
|
||||||
(tools/register-page url [#'main] title)
|
(tools/register-page url [#'main] title)
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
(string/split src #"\n(?=[(])"))
|
(string/split src #"\n(?=[(])"))
|
||||||
|
|
||||||
(defn src-defs [parts]
|
(defn src-defs [parts]
|
||||||
(let [ws #"[^ \t]+"]
|
(let [ws #"[^ \t\n]+"]
|
||||||
(into {} (for [x parts]
|
(into {} (for [x parts]
|
||||||
[(->> x (re-seq ws) second keyword) x]))))
|
[(->> x (re-seq ws) second keyword) x]))))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue