reagent/demo/reagentdemo/news/news060.cljs

109 lines
3.8 KiB
Plaintext
Raw Normal View History

2015-12-06 20:56:03 +00:00
(ns reagentdemo.news.news060
(:require [reagent.core :as r]
[reagent.debug :refer-macros [dbg println]]
[reagentdemo.syntax :as s]
[sitetools.core :as tools :refer [link]]
[reagentdemo.common :as common :refer [demo-component]]))
(def url "/news/news060-alpha.html")
(def title "News in 0.6.0-alpha")
(def ns-src (s/syntaxed "(ns example.core
(:require [reagent.core :as r]))"))
(defonce app-state (r/atom {:people
{1 {:first-name "John"
:last-name "Smith"}
2 {:first-name "Maggie"
:last-name "Johnson"}}}))
(defn people []
(:people @app-state))
(defn person-keys []
2015-12-07 10:22:49 +00:00
(-> @(r/track people)
keys
sort))
2015-12-06 20:56:03 +00:00
(defn person [id]
2015-12-07 10:22:49 +00:00
(-> @(r/track people)
(get id)))
2015-12-06 20:56:03 +00:00
(defn name-comp [id]
(let [p @(r/track person id)]
[:li
(:first-name p) " " (:last-name p)]))
(defn name-list []
(let [ids @(r/track person-keys)]
[:ul
(for [i ids]
^{:key i} [name-comp i])]))
(defn main [{:keys [summary]}]
[:div.reagent-demo
[:h1 [link {:href url} title]]
[:div.demo-text
[:p "Reagent 0.6.0-alpha contains new reactivity helpers, better
integration with native React components, a new version of React,
and much more. "]
(if summary
[link {:href url :class 'news-read-more} "Read more"]
[:div.demo-text
[:h2 "Use any function as a reactive value"]
[:p [:code "reagent.core/track"] " takes a function, and
2015-12-07 10:22:49 +00:00
optional arguments for that function, and gives a
derefable (i.e ”atom-like”) value, containing whatever is
2015-12-06 20:56:03 +00:00
returned by that function. If the tracked function depends on a
Reagent atom, the function is called again whenever that atom
changes just like a Reagent component function. If the value
returned by " [:code "track"] " is used in a component, the
component is re-rendered when the value returned by the
function changes. "]
[:p "In other words, " [:code "@(r/track foo x)"] " gives the
same result as " [:code "(foo x)"] " but in the first case,
2015-12-07 10:22:49 +00:00
foo is only called again when the atom(s) it depends on
2015-12-06 20:56:03 +00:00
changes."]
[:p "Here's an example: "]
[demo-component {:comp name-list
:src (s/src-of [:app-state
:people
:person-keys
:person
:name-comp
:name-list])}]
[:p "Here, the " [:code "name-list"] " component will only be
2015-12-07 10:22:49 +00:00
re-rendered if the keys of the " [:code ":people"] " map
2015-12-06 20:56:03 +00:00
changes. Every " [:code "name-comp"] " only renders again when
needed, etc."]
2015-12-07 10:22:49 +00:00
[:p "Use of " [:code "track"] " can improve performance in
three ways:" ]
[:ul
[:li "It can be used as a cache for an expensive function,
that is automatically updated if that function depends on Reagent
atoms (or other tracks, cursors, etc)."]
[:li "It can also be used to limit the number of times a
component is re-rendered. The user of " [:code "track"] " is
only updated when the functions result changes. In other
words, you can use track as a kind of generalized, read-only
cursor."]
[:li "Every use of " [:code "track"] " with the same arguments
will only result in one execution of the function. E.g the two
uses of " [:code "@(r/track people)"] " in the example above
will only result in one call to the " [:code "people"] "
function (both initially, and when the state atom changes)."]]
2015-12-06 20:56:03 +00:00
])]])
(tools/register-page url [#'main] title)