{"id":307684,"date":"2020-07-29T15:00:49","date_gmt":"2020-07-29T15:00:49","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=307684"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2020-07-29T15:00:49","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=307684","title":{"rendered":"Reagent: \u041c\u0438\u043d\u0438\u043c\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0439 React \u0434\u043b\u044f ClojureScript"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/505940\/\">\u0425\u0430\u0431\u0440, \u043f\u0440\u0438\u0432\u0435\u0442.<\/p>\n<p>  \u042f \u2014 PM, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u0435\u0437\u0435\u0442 \u0432 \u0442\u043e, \u0447\u0442\u043e \u0435\u0433\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0436\u0440\u0430\u0442\u044c. \u0422\u0430\u043a \u0447\u0442\u043e, \u044f \u043f\u0435\u0440\u0435\u0432\u0435\u043b\u0430 \u0447\u0430\u0441\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043f\u043e Reagent, \u0435\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u0432\u044b\u043b\u043e\u0436\u0443 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/rd\/mt\/nx\/rdmtnxgrx3jub7exra_azo09pcg.png\"><br \/>  <font color=\"#A9A9A9\">In the no-holds-barred world of coding, the end justifies the extreme.<\/font><\/p>\n<h3><font color=\"#191970\">\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 Reagent<\/font><\/h3>\n<p>  <a href=\"https:\/\/github.com\/reagent-project\/reagent\" rel=\"nofollow\">Reagent<\/a> \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u043e\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 <a href=\"https:\/\/github.com\/clojure\/clojurescript\" rel=\"nofollow\">ClojureScript<\/a> \u0438 <a href=\"https:\/\/reactjs.org\/\" rel=\"nofollow\">React<\/a>. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b React, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 ClojureScript \u0438 \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <a href=\"https:\/\/github.com\/weavejester\/hiccup\" rel=\"nofollow\">Hiccup<\/a>-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441.<\/p>\n<p>  \u0426\u0435\u043b\u044c Reagent \u2014 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u0430\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043f\u043e\u043d\u044f\u0442\u0438\u0439, \u0438 \u0431\u044b\u0442\u044c \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u0432\u0430\u043c \u0440\u0435\u0434\u043a\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  \u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 Reagent <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lisp\">(defn simple-component []   [:div    [:p &quot;I am a component!&quot;]    [:p.someclass     &quot;I have &quot; [:strong &quot;bold&quot;]     [:span {:style {:color &quot;red&quot;}} &quot; and red &quot;] &quot;text.&quot;]])<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <a name=\"habracut\"><\/a><br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/28\/xx\/zk\/28xxzkkwifoscwgelyue1rjj8yu.png\"><\/p>\n<p>  \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0432\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044f \u0432\u043d\u0443\u0442\u0440\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u0430\u043a \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435:<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lisp\">(defn simple-parent []   [:div    [:p &quot;I include simple-component.&quot;]    [simple-component]])<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/x8\/cx\/i3\/x8cxi3nrxw6f1ldtuahgph2cq88.png\"><\/p>\n<p>  \u0414\u0430\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 Clojure. <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u0430\u043a \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435:<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lisp\">(defn hello-component [name]   [:p &quot;Hello, &quot; name &quot;!&quot;])  (defn say-hello []   [hello-component &quot;world&quot;])<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/jq\/fm\/w5\/jqfmw5cebtkcfvkmlavub29tuhq.png\"><\/p>\n<p>  <b>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/b>: \u0412 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u0432\u044b\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 hello-component \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e Clojure, \u0430 \u043d\u0435 \u043a\u0430\u043a \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 Reagent, \u0442.\u0435. \u0441 \u043a\u0440\u0443\u0433\u043b\u044b\u043c\u0438 \u0441\u043a\u043e\u0431\u043a\u0430\u043c\u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0445 \u0441\u043a\u043e\u0431\u043e\u043a. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043e\u0442\u043b\u0438\u0447\u0438\u0435\u043c \u0431\u044b\u043b\u0430 \u0431\u044b \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u00ab\u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435\u00bb \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b Reagent \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c. \u041e\u0434\u043d\u0430\u043a\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b (\u0441\u043c. \u043d\u0438\u0436\u0435) \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0445 \u0441\u043a\u043e\u0431\u043a\u0430\u0445.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0412\u043e\u0442 \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432:<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lisp\">(defn lister [items]   [:ul    (for [item items]      ^{:key item} [:li &quot;Item &quot; item])])  (defn lister-user []   [:div    &quot;Here is a list:&quot;    [lister (range 3)]])<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/m9\/01\/ty\/m901typgzkxoreaauemvkstav5c.png\"><\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f \u0432\u044b\u0448\u0435 \u0447\u0430\u0441\u0442\u044c ^{: key item} \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435, \u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430 \u043a \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u043e\u043c \u0441\u043f\u0438\u0441\u043a\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0445\u043e\u0440\u043e\u0448\u0435\u0439 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u043e\u0439 \u0438 \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0441\u043f\u0438\u0441\u043a\u043e\u0432. \u041a\u043b\u044e\u0447 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u0434\u0430\u043d \u043b\u0438\u0431\u043e (\u043a\u0430\u043a \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435) \u043a\u0430\u043a \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435, \u043b\u0438\u0431\u043e \u043a\u0430\u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442 :key \u0432 \u043f\u0435\u0440\u0432\u043e\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 (\u0435\u0441\u043b\u0438 \u044d\u0442\u043e map). \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 React.<\/p>\n<h3><font color=\"#191970\">\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0432 React<\/font><\/h3>\n<p>  \u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e atom \u0438\u0437 Reagent. \u041e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0438 \u0432 clojure.core, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0434\u0435\u0440\u0435\u0444\u0430\u0435\u0442\u0441\u044f\/\u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f (<a href=\"https:\/\/clojuredocs.org\/clojure.core\/deref\" rel=\"nofollow\">deref<\/a>). \u041b\u044e\u0431\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439 atom, \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u0441\u044f \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435:<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lisp\">(ns example   (:require [reagent.core :as r])) (def click-count (r\/atom 0))  (defn counting-component []   [:div    &quot;The atom &quot; [:code &quot;click-count&quot;] &quot; has value: &quot;    @click-count &quot;. &quot;    [:input {:type &quot;button&quot; :value &quot;Click me!&quot;             :on-click #(swap! click-count inc)}]])<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/a6\/iq\/li\/a6iqlijffc896xfdpsn0nh6gzzc.gif\"><\/div>\n<p>  \u0418\u043d\u043e\u0433\u0434\u0430 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u0445\u043e\u0442\u0435\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0442\u0435\u0439\u0442 \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435. \u042d\u0442\u043e \u043b\u0435\u0433\u043a\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438 \u0441 \u0430\u0442\u043e\u043c\u043e\u043c.<\/p>\n<p>  \u041c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c setTimeout, \u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u043e\u043c:  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lisp\">(ns example   (:require [reagent.core :as r])) (def click-count (r\/atom 0))  (defn counting-component []   [:div    &quot;The atom &quot; [:code &quot;click-count&quot;] &quot; has value: &quot;    @click-count &quot;. &quot;    [:input {:type &quot;button&quot; :value &quot;Click me!&quot;             :on-click #(swap! click-count inc)}]])<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/gh\/ea\/k-\/gheak-bdxgkopayr6znwmdijyde.gif\"><\/p>\n<p>  \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c Reagent: \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u0442\u0435\u043c\u0438 \u0436\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438, \u0447\u0442\u043e \u0438 \u043f\u0435\u0440\u0432\u0430\u044f.<\/p>\n<p>  \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0432\u043d\u043e\u0432\u044c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043d\u0435 \u043f\u0440\u0438\u0431\u0435\u0433\u0430\u044f \u043a \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u043c \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 Reagent.<\/p>\n<p>  \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u044f \u0430\u0442\u043e\u043c, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438. <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f:<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lisp\">(ns example   (:require [reagent.core :as r])) (defn atom-input [value]   [:input {:type &quot;text&quot;            :value @value            :on-change #(reset! value (-&gt; % .-target .-value))}])  (defn shared-state []   (let [val (r\/atom &quot;foo&quot;)]     (fn []       [:div        [:p &quot;The value is now: &quot; @val]        [:p &quot;Change it here: &quot; [atom-input val]]])))<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/av\/ti\/ld\/avtildc4lp1ly7ll9_mv7gvq3a4.gif\"><\/div>\n<p>  <b>\u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/b>: \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u043b\u044e\u0431\u044b\u043c\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u2014 \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043e\u043d\u0438 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u044b. \u0412\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u043d\u043e \u0442\u043e\u0433\u0434\u0430 \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u0441\u044f \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. Reagent \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0447\u0442\u043e \u0434\u0432\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0440\u0430\u0432\u043d\u044b, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u0438\u043c \u0438 \u0442\u0435\u043c \u0436\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c.<\/p>\n<h3><font color=\"#191970\">\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 API<\/font><\/h3>\n<p>  Reagent \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e API React, \u043d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0430 \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430\u044f \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439: reagent.dom\/render.<\/p>\n<p>  \u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u0432\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430: \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438 DOM-\u0443\u0437\u0435\u043b. <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0434 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lisp\">(ns example   (:require [reagent.core :as r])) (defn simple-component []   [:div    [:p &quot;I am a component!&quot;]    [:p.someclass     &quot;I have &quot; [:strong &quot;bold&quot;]     [:span {:style {:color &quot;red&quot;}} &quot; and red &quot;] &quot;text.&quot;]])  (defn render-simple []   (rdom\/render     [simple-component]     (.-body js\/document)))<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<h3><font color=\"#191970\">\u0421\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044f \u0432\u0441\u0435 \u0432\u043c\u0435\u0441\u0442\u0435<\/font><\/h3>\n<p>  \u0412\u043e\u0442 \u0431\u043e\u043b\u0435\u0435 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440: \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440 BMI.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0414\u0430\u043d\u043d\u044b\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u043c reagent.core\/atom: map \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u043a\u043b\u044e\u0447\u0430\u043c\u0438: \u0432\u044b\u0441\u043e\u0442\u0430, \u0432\u0435\u0441 \u0438 BMI.<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lisp\">(ns example   (:require [reagent.core :as r])) (defn calc-bmi [{:keys [height weight bmi] :as data}]   (let [h (\/ height 100)]     (if (nil? bmi)       (assoc data :bmi (\/ weight (* h h)))       (assoc data :weight (* bmi h h)))))  (def bmi-data (r\/atom (calc-bmi {:height 180 :weight 80})))  (defn slider [param value min max invalidates]   [:input {:type &quot;range&quot; :value value :min min :max max            :style {:width &quot;100%&quot;}            :on-change (fn [e]                         (let [new-value (js\/parseInt (.. e -target -value))]                           (swap! bmi-data                                  (fn [data]                                    (-&gt; data                                      (assoc param new-value)                                      (dissoc invalidates)                                      calc-bmi)))))}])  (defn bmi-component []   (let [{:keys [weight height bmi]} @bmi-data         [color diagnose] (cond                           (&lt; bmi 18.5) [&quot;orange&quot; &quot;underweight&quot;]                           (&lt; bmi 25) [&quot;inherit&quot; &quot;normal&quot;]                           (&lt; bmi 30) [&quot;orange&quot; &quot;overweight&quot;]                           :else [&quot;red&quot; &quot;obese&quot;])]     [:div      [:h3 &quot;BMI calculator&quot;]      [:div       &quot;Height: &quot; (int height) &quot;cm&quot;       [slider :height height 100 220 :bmi]]      [:div       &quot;Weight: &quot; (int weight) &quot;kg&quot;       [slider :weight weight 30 150 :bmi]]      [:div       &quot;BMI: &quot; (int bmi) &quot; &quot;       [:span {:style {:color color}} diagnose]       [slider :bmi bmi 10 50 :weight]]]))<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/sj\/gm\/fm\/sjgmfm06093jonazdnugzf-rabs.gif\"><\/div>\n<p>  <\/p>\n<h3><font color=\"#191970\">\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/font><\/h3>\n<p>  React \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u044b\u0439, \u043a\u0430\u043a \u0438 Reagent. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, Reagent \u0431\u0443\u0434\u0435\u0442 \u0434\u0430\u0436\u0435 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 React \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435\u0433\u0434\u0430, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f\u043c, \u0441\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u043c ClojureScript.<\/p>\n<p>  \u0421\u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u044f\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u0438\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c. \u0420\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u043c\u0435\u043d\u043e\u0439 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0430\u0442\u043e\u043c\u0430, \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u0438\u043b\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430.<\/p>\n<p>  \u0412\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u044e identical?, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. Map\u2019\u044b, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c, \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u0430\u043a \u0436\u0435: \u043e\u043d\u0438 \u0441\u0447\u0438\u0442\u0430\u044e\u0442\u0441\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b\u043c\u0438, \u0435\u0441\u043b\u0438 \u0432\u0441\u0435 \u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b. \u042d\u0442\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u0438 \u043a \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c React, \u0442\u0430\u043a\u0438\u043c \u043a\u0430\u043a :div, :p \u0438 \u0442. \u0434.<\/p>\n<p>  \u0412\u0441\u0435 \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0437\u0430\u0431\u043e\u0442\u0438\u0442\u044c\u0441\u044f \u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041f\u0440\u043e\u0441\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u0435 \u0441\u0432\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043a\u0430\u043a \u0443\u0433\u043e\u0434\u043d\u043e \u2014 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u044b\u043c.<\/p>\n<p>  \u0415\u0441\u0442\u044c \u043f\u0430\u0440\u0430 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0439, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u0430\u043c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u043e\u0437\u0430\u0431\u043e\u0442\u0438\u0442\u044c\u0441\u044f. \u0415\u0441\u043b\u0438 \u0432\u044b \u0434\u0430\u0434\u0438\u0442\u0435 Reagent \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0432\u0430\u043c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u043d\u0430\u0431\u0434\u0438\u0442\u044c \u0438\u0445 \u0432\u0441\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c :key \u0434\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 (\u0441\u043c. \u0432\u044b\u0448\u0435). \u0422\u0430\u043a\u0436\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u0446\u0435\u043b\u043e\u043c \u043d\u0435 \u0440\u0430\u0432\u043d\u044b \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u043a\u043e\u0434 \u0438 \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u0435.<\/p>\n<p>  \u041d\u043e \u043e\u043f\u044f\u0442\u044c \u0436\u0435, \u0432 \u0446\u0435\u043b\u043e\u043c, \u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e React \u0438 Reagent \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u044b\u043c\u0438. \u0418\u043c\u0435\u043d\u043d\u043e <a href=\"https:\/\/reagent-project.github.io\/\" rel=\"nofollow\">\u044d\u0442\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430<\/a> \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 Reagent \u0441 \u0442\u044b\u0441\u044f\u0447\u0430\u043c\u0438 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 (\u043a\u0430\u0436\u0434\u0430\u044f \u0441\u043a\u043e\u0431\u043a\u0430 \u0438 \u0442.\u0434. \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u043a\u043e\u0434\u0430 \u2014 \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442), \u0438 \u0432\u0441\u0435 \u0436\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0435\u043a\u0443\u043d\u0434\u0443, \u043d\u0435 \u043d\u0430\u0433\u0440\u0443\u0436\u0430\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440.<\/p>\n<p>  \u041a\u0441\u0442\u0430\u0442\u0438, <a href=\"https:\/\/reagent-project.github.io\/\" rel=\"nofollow\">\u0442\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430<\/a> \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u0440\u0443\u0433\u043e\u0439 \u0442\u0440\u044e\u043a React: \u0432\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0432\u0430\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Nodejs \u0438 reagent.dom.server\/render-to-string. \u041a\u043e\u0433\u0434\u0430 \u043e\u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440, React \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043a \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c\u0443 DOM-\u0434\u0435\u0440\u0435\u0432\u0443.<\/p>\n<h3><font color=\"#191970\">\u041f\u043e\u043b\u043d\u0430\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f<\/font><\/h3>\n<p>  Reagent \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u0430\u0440\u043e\u0439 \u043f\u043e\u043b\u043d\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432, \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u043d\u044b\u043c\u0438 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 Leiningen \u0438 \u0432\u0441\u0435\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c. <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0412\u043e\u0442 \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438:<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lisp\">(ns simpleexample.core   (:require [reagent.core :as r]             [reagent.dom :as rdom]             [clojure.string :as str]))  (defonce timer (r\/atom (js\/Date.)))  (defonce time-color (r\/atom &quot;#f34&quot;))  (defonce time-updater (js\/setInterval                        #(reset! timer (js\/Date.)) 1000))  (defn greeting [message]   [:h1 message])  (defn clock []   (let [time-str (-&gt; @timer .toTimeString (str\/split &quot; &quot;) first)]     [:div.example-clock      {:style {:color @time-color}}      time-str]))  (defn color-input []   [:div.color-input    &quot;Time color: &quot;    [:input {:type &quot;text&quot;             :value @time-color             :on-change #(reset! time-color (-&gt; % .-target .-value))}]])  (defn simple-example []   [:div    [greeting &quot;Hello world, it is now&quot;]    [clock]    [color-input]])  (defn ^:export run []   (rdom\/render [simple-example] (js\/document.getElementById &quot;app&quot;)))<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/xb\/ww\/rw\/xbwwrwlrbl3n_p5rsyjzjmhgjsy.gif\"><\/div>\n<p>  <\/p>\n<h3><font color=\"#191970\"> Todomvc <\/font><\/h3>\n<p>  \u0421\u043f\u0438\u0441\u043e\u043a \u0434\u0435\u043b (ToDo List) \u0432 Reagent (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0440\u043e\u0443\u0442\u0438\u043d\u0433\u0430 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445) <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lisp\">(ns todomvc.core   (:require [reagent.core :as r]             [reagent.dom :as rdom]             [clojure.string :as str]))  (defonce todos (r\/atom (sorted-map)))  (defonce counter (r\/atom 0))  (defn add-todo [text]   (let [id (swap! counter inc)]     (swap! todos assoc id {:id id :title text :done false})))  (defn toggle [id] (swap! todos update-in [id :done] not)) (defn save [id title] (swap! todos assoc-in [id :title] title)) (defn delete [id] (swap! todos dissoc id))  (defn mmap [m f a] (-&gt;&gt; m (f a) (into (empty m)))) (defn complete-all [v] (swap! todos mmap map #(assoc-in % [1 :done] v))) (defn clear-done [] (swap! todos mmap remove #(get-in % [1 :done])))  (defonce init (do                 (add-todo &quot;Rename Cloact to Reagent&quot;)                 (add-todo &quot;Add undo demo&quot;)                 (add-todo &quot;Make all rendering async&quot;)                 (add-todo &quot;Allow any arguments to component functions&quot;)                 (complete-all true)))  (defn todo-input [{:keys [title on-save on-stop]}]   (let [val (r\/atom title)         stop #(do (reset! val &quot;&quot;)                   (if on-stop (on-stop)))         save #(let [v (-&gt; @val str str\/trim)]                 (if-not (empty? v) (on-save v))                 (stop))]     (fn [{:keys [id class placeholder]}]       [:input {:type &quot;text&quot; :value @val                :id id :class class :placeholder placeholder                :on-blur save                :on-change #(reset! val (-&gt; % .-target .-value))                :on-key-down #(case (.-which %)                                13 (save)                                27 (stop)                                nil)}])))  (def todo-edit (with-meta todo-input                  {:component-did-mount #(.focus (rdom\/dom-node %))}))  (defn todo-stats [{:keys [filt active done]}]   (let [props-for (fn [name]                     {:class (if (= name @filt) &quot;selected&quot;)                      :on-click #(reset! filt name)})]     [:div      [:span#todo-count       [:strong active] &quot; &quot; (case active 1 &quot;item&quot; &quot;items&quot;) &quot; left&quot;]      [:ul#filters       [:li [:a (props-for :all) &quot;All&quot;]]       [:li [:a (props-for :active) &quot;Active&quot;]]       [:li [:a (props-for :done) &quot;Completed&quot;]]]      (when (pos? done)        [:button#clear-completed {:on-click clear-done}         &quot;Clear completed &quot; done])]))  (defn todo-item []   (let [editing (r\/atom false)]     (fn [{:keys [id done title]}]       [:li {:class (str (if done &quot;completed &quot;)                         (if @editing &quot;editing&quot;))}        [:div.view         [:input.toggle {:type &quot;checkbox&quot; :checked done                         :on-change #(toggle id)}]         [:label {:on-double-click #(reset! editing true)} title]         [:button.destroy {:on-click #(delete id)}]]        (when @editing          [todo-edit {:class &quot;edit&quot; :title title                      :on-save #(save id %)                      :on-stop #(reset! editing false)}])])))  (defn todo-app [props]   (let [filt (r\/atom :all)]     (fn []       (let [items (vals @todos)             done (-&gt;&gt; items (filter :done) count)             active (- (count items) done)]         [:div          [:section#todoapp           [:header#header            [:h1 &quot;todos&quot;]            [todo-input {:id &quot;new-todo&quot;                         :placeholder &quot;What needs to be done?&quot;                         :on-save add-todo}]]           (when (-&gt; items count pos?)             [:div              [:section#main               [:input#toggle-all {:type &quot;checkbox&quot; :checked (zero? active)                                   :on-change #(complete-all (pos? active))}]               [:label {:for &quot;toggle-all&quot;} &quot;Mark all as complete&quot;]               [:ul#todo-list                (for [todo (filter (case @filt                                     :active (complement :done)                                     :done :done                                     :all identity) items)]                  ^{:key (:id todo)} [todo-item todo])]]              [:footer#footer               [todo-stats {:active active :done done :filt filt}]]])]          [:footer#info           [:p &quot;Double-click to edit a todo&quot;]]]))))  (defn ^:export run []   (rdom\/render [todo-app] (js\/document.getElementById &quot;app&quot;)))<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/gs\/ks\/xe\/gsksxes4zqjrzmk7m7trxwijd-g.gif\"><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u043e\u0441\u0442\u044c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e \u0437\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u0432 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0435 <a href=\"https:\/\/habr.com\/ru\/users\/zombiqwerty\/\" class=\"user_link\">zombiQWERTY<\/a>.  <\/div>\n<\/p><\/div>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/505940\/\"> https:\/\/habr.com\/ru\/post\/505940\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/505940\/\">\u0425\u0430\u0431\u0440, \u043f\u0440\u0438\u0432\u0435\u0442.<\/p>\n<p>  \u042f \u2014 PM, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u0435\u0437\u0435\u0442 \u0432 \u0442\u043e, \u0447\u0442\u043e \u0435\u0433\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0436\u0440\u0430\u0442\u044c. \u0422\u0430\u043a \u0447\u0442\u043e, \u044f \u043f\u0435\u0440\u0435\u0432\u0435\u043b\u0430 \u0447\u0430\u0441\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043f\u043e Reagent, \u0435\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u0432\u044b\u043b\u043e\u0436\u0443 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/rd\/mt\/nx\/rdmtnxgrx3jub7exra_azo09pcg.png\"><br \/>  <font color=\"#A9A9A9\">In the no-holds-barred world of coding, the end justifies the extreme.<\/font><\/p>\n<h3><font color=\"#191970\">\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 Reagent<\/font><\/h3>\n<p>  <a href=\"https:\/\/github.com\/reagent-project\/reagent\" rel=\"nofollow\">Reagent<\/a> \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u043e\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 <a href=\"https:\/\/github.com\/clojure\/clojurescript\" rel=\"nofollow\">ClojureScript<\/a> \u0438 <a href=\"https:\/\/reactjs.org\/\" rel=\"nofollow\">React<\/a>. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b React, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 ClojureScript \u0438 \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <a href=\"https:\/\/github.com\/weavejester\/hiccup\" rel=\"nofollow\">Hiccup<\/a>-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441.<\/p>\n<p>  \u0426\u0435\u043b\u044c Reagent \u2014 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u0430\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043f\u043e\u043d\u044f\u0442\u0438\u0439, \u0438 \u0431\u044b\u0442\u044c \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u0432\u0430\u043c \u0440\u0435\u0434\u043a\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  \u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 Reagent <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lisp\">(defn simple-component []   [:div    [:p &quot;I am a component!&quot;]    [:p.someclass     &quot;I have &quot; [:strong &quot;bold&quot;]     [:span {:style {:color &quot;red&quot;}} &quot; and red &quot;] &quot;text.&quot;]])<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-307684","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/307684","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=307684"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/307684\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=307684"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=307684"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=307684"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}