{"id":278821,"date":"2016-04-22T00:20:04","date_gmt":"2016-04-21T20:20:04","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=278821"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=278821","title":{"rendered":"React.js \u2014 \u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u0434\u043b\u044f Rails \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432"},"content":{"rendered":"<p>       <i>\u041d\u0430 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u0442\u0430\u043a\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u044b \u2014 \u043c\u043e\u0439 \u0432\u043a\u043b\u0430\u0434 \u0432 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435 rails \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430.<\/i><br \/>  <i>\u0414\u0430\u043b\u044c\u0448\u0435 \u0432 \u0442\u0435\u043a\u0441\u0442\u0435 \u0432\u0441\u0435 \u0447\u0442\u043e \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043e \u043a\u0443\u0440\u0441\u0438\u0432\u043e\u043c \u043c\u043e\u0438 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f (\u0442\u0430\u043a\u0438\u0445 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u043c\u043d\u043e\u0433\u043e:) )<\/i><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/7f8\/0c6\/fe0\/7f80c6fe03d73212bc0768490700c3de.png\" alt=\"image\"\/><\/p>\n<p>  <b>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 React.js<\/b><\/p>\n<p>  <b>React.js<\/b> \u044d\u0442\u043e \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u043f\u0430\u0440\u0435\u043d\u044c \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u044b JavaScript \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432, \u043e\u043d \u0441\u0438\u044f\u0435\u0442 \u0441\u0432\u043e\u0435\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u043e\u0439. \u041a\u043e\u0433\u0434\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 <b>MVC<\/b> (Model View Controller) \u043f\u043e\u0434\u0445\u043e\u0434, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043a\u0430\u0437\u0430\u0442\u044c React&#8217;\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e View (\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435) (\u0444\u0430\u043a\u0442 \u2014 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u044e\u0434\u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u0447\u0430\u0441\u0442\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f (V) \u044d\u0442\u0438\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 c \u043f\u043e\u043c\u043e\u0449\u044c\u044e React).<\/p>\n<p>  \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u0440\u0435\u0430\u043a\u0442\u043e\u043c \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u044b \u043d\u0430 2\u0445 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430\u0445 \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438 \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u043b\u043a\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0438\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445. \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0447\u0442\u043e \u0440\u0435\u0431\u044f\u0442\u0430 \u0438\u0437 Facebook \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043e\u0434\u043d\u043e\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0439 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u044f \u0447\u0442\u043e \u043d\u0430\u0448 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441(UI) \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<p>  \u041e\u0434\u043d\u0430 \u0445\u043e\u0440\u043e\u0448\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c React.js \u044d\u0442\u043e \u0442\u043e \u0447\u0442\u043e \u043e\u043d \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043a\u0430\u043a\u0438\u0445-\u043b\u0438\u0431\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0447\u0442\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0435\u043c\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u043e\u0441\u0442\u044c \u0441 \u043b\u044e\u0431\u043e\u0439 js \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439. \u041f\u043e\u043b\u044c\u0437\u0443\u044f\u0441\u044c \u044d\u0442\u0438\u043c, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u044c \u0435\u0433\u043e \u0432 \u043d\u0430\u0448 Rails \u0441\u0442\u0435\u043a \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u00abRails \u043d\u0430 \u0441\u0442\u0435\u0440\u043e\u0438\u0434\u0430\u0445\u00bb.<\/p>\n<h1>\u041c\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h1>\n<p>  \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0433\u0430\u0439\u0434\u0430 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u043d\u0443\u043b\u044f \u0447\u0442\u043e \u0431\u044b \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u041a\u0430\u0436\u0434\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c(<i>\u0434\u0430\u043b\u044c\u0448\u0435, \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0447\u0442\u043e \u0438 Record<\/i>) \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0434\u0430\u0442\u044b, \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430. \u0417\u0430\u043f\u0438\u0441\u044c \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u041a\u0440\u0435\u0434\u0438\u0442(Credit) \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u0441\u0443\u043c\u043c\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0443\u043b\u044f, \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430r \u0434\u0435\u0431\u0435\u0442. \u0412\u043e\u0442 \u043c\u0430\u043a\u0435\u0442 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/3b1\/641\/e13\/3b1641e134a4819b1ba616aa202a05b8.png\" alt=\"image\"\/><\/p>\n<p>  \u0421\u0443\u043c\u043c\u0430\u0440\u043d\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u0435\u0441\u0442\u0438 \u0441\u0435\u0431\u044f \u0442\u0430\u043a:  <\/p>\n<ol>\n<li>\u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u0447\u0435\u0440\u0435\u0437 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u0443\u044e \u0444\u043e\u0440\u043c\u0443, \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 <\/li>\n<li>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u0443\u044e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c <\/li>\n<li>\u041a\u043b\u0438\u043a\u043d\u0443\u0432 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 Delete \u043e\u043d \u0443\u0434\u0430\u043b\u0438\u0442 \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u044e \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b <\/li>\n<li>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u043e\u043a\u0441\u043e\u0432 \u0432 \u0432\u0435\u0440\u0445\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b <\/li>\n<\/ol>\n<h1> \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f React.js \u0432 Rails \u043f\u0440\u043e\u0435\u043a\u0442 <\/h1>\n<p>  <a name=\"habracut\"><\/a><br \/>  \u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u0448 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e <b>Accounts<\/b>  <\/p>\n<pre><code class=\"bash\">rails new accounts <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>bootstrap<\/code>. \u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u0440\u0430\u043c\u043a\u0438 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u043d\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0433\u0435\u043c <code>bootstrap-sass<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u0438\u0437 <a href=\"https:\/\/github.com\/twbs\/bootstrap-sass\">\u0433\u0438\u0442 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f<\/a>.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d. \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c <code>React<\/code>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0433\u0430\u0439\u0434\u0430 \u044f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u0441 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0433\u0435\u043c\u0430 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u0440\u0443\u0442\u044b\u0435 \u0444\u0438\u0447\u0438 \u044d\u0442\u043e\u0433\u043e \u0433\u0435\u043c\u0430, \u043d\u043e \u0435\u0441\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0439 \u0446\u0435\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u044b\u0432\u0430\u0442\u044c Rails \u0438\u043b\u0438 \u043c\u043e\u0436\u0435\u043c \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u043d\u0430\u0448\u0443 <code>javascripts<\/code> \u043f\u0430\u043f\u043a\u0443.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0438\u0441\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 Rails \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432\u044b \u0437\u043d\u0430\u0435\u0442\u0435 \u043a\u0430\u043a \u043b\u0435\u0433\u043a\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0433\u0435\u043c: \u0414\u043e\u0431\u0430\u0432\u0442\u0435 <code>react-rails<\/code> \u0432 \u0432\u0430\u0448 <code>Gemfile<\/code>  <\/p>\n<pre><code class=\"ruby\">  gem 'react-rails', '~&gt; 1.0' <\/code><\/pre>\n<p>  \u0417\u0430\u0442\u0435\u043c \u043b\u044e\u0431\u0435\u0437\u043d\u043e \u0441\u043a\u0430\u0436\u0438\u0442\u0435 \u0440\u0435\u043b\u044c\u0441\u0430\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0433\u0435\u043c  <\/p>\n<pre><code class=\"bash\">bundle install <\/code><\/pre>\n<p>  <b>React-rails<\/b> \u0438\u0434\u0435\u0442 \u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0444\u0430\u0439\u043b <code>components.js<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0430\u043f\u043a\u0438 <code>app\/assets\/javascripts<\/code> \u0433\u0434\u0435 \u0438 \u0431\u0443\u0434\u0443\u0442 \u0436\u0438\u0442\u044c \u043d\u0430\u0448\u0438 <b>React<\/b> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.  <\/p>\n<pre><code class=\"bash\">rails g react:install <\/code><\/pre>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u0432 \u0432\u0430\u0448 \u0444\u0430\u0439\u043b <code>application.js<\/code> \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u2014 \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 3 \u043d\u043e\u0432\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438:  <\/p>\n<pre><code class=\"javascript\">\/\/= require react \/\/= require react_ujs \/\/= require components <\/code><\/pre>\n<p>  \u041f\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443, \u044d\u0442\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f React \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438 \u043f\u043e\u0445\u043e\u0436\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 <code>ujs<\/code>.\u041a\u0430\u043a \u0432\u044b \u043c\u043e\u0433\u043b\u0438 \u0434\u043e\u0433\u0430\u0434\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0444\u0430\u0439\u043b\u0430 <code>react-rails<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u043d\u0430\u0432\u044f\u0437\u0447\u0438\u0432\u044b\u0439 JS \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0430\u0448\u0438 React \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0430 \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c Turbolinks \u0441\u043e\u0431\u044b\u0442\u0438\u044f.<\/p>\n<h1>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430<\/h1>\n<p>  \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c <code>Record<\/code> \u0440\u0435\u0441\u0443\u0440\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0434\u0430\u0442\u044b(date) \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430(title) \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430(amount).<br \/>  \u0412\u0437\u0430\u043c\u0435\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438<code>scaffold<\/code>&#8216;a, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>resource<\/code> \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440,<br \/>  \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e scaffold \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430. \u0414\u0440\u0443\u0433\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043c\u043e\u0433\u043b\u0430 \u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u043a\u0430\u0444\u0444\u043e\u043b\u0434 \u0438 \u0442\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043b\u0430 \u0431\u044b \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0444\u0430\u0439\u043b\u044b\/\u043c\u0435\u0442\u043e\u0434\u044b \u043d\u043e \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442 \u043c\u043e\u0436\u0435\u0442 \u0441\u0442\u0430\u0442\u044c \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0433\u0440\u044f\u0437\u043d\u044b\u043c. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e, \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443:  <\/p>\n<pre><code class=\"bash\">rails g resource Record title date:date amount:float <\/code><\/pre>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0439 \u043c\u0430\u0433\u0438\u0438 \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c(Model) \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440(Controller) \u0438 \u0440\u043e\u0443\u0442\u044b(routes). \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438:  <\/p>\n<pre><code class=\"bash\">rake db:create db:migrate <\/code><\/pre>\n<p>  \u041f\u043b\u044e\u0441 \u043a\u043e \u0432\u0441\u0435\u043c\u0443 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0430\u0440\u0443 \u0437\u0430\u043f\u0438\u0441\u0435\u0439(records) \u0447\u0435\u0440\u0435\u0437  <\/p>\n<pre><code class=\"bash\">rails console Record.create title: 'Record 1', date: Date.today, amount: 500 Record.create title: 'Record 2', date: Date.today, amount: -100 <\/code><\/pre>\n<p>  \u041d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0430\u0448 \u0441\u0435\u0440\u0432\u0435\u0440  <\/p>\n<pre><code class=\"bash\">rails s<\/code><\/pre>\n<p>  \u0413\u043e\u0442\u043e\u0432\u043e! \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434.<\/p>\n<h1>\u0412\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b: \u0421\u043f\u0438\u0441\u043e\u043a Records<\/h1>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u043f\u0435\u0440\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u043b\u044e\u0431\u0443\u044e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u0432\u043d\u0443\u0442\u0440\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<br \/>  \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c <code>index<\/code> \u044d\u043a\u0448\u043d \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 <code>RecordsController<\/code>:  <\/p>\n<pre><code class=\"ruby\"># app\/controllers\/records_controller.rb  class RecordsController &lt; ApplicationController    def index      @records = Record.all    end end <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b <code>index.html.erb<\/code>\u0432<code>apps\/views\/records\/<\/code>, \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0431\u0443\u0434\u0435\u0442 \u043c\u043e\u0441\u0442\u043e\u043c \u043c\u0435\u0436\u0434\u0443 \u043d\u0430\u0448\u0438\u043c Rails \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 React. \u0414\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0445\u0435\u043b\u043f\u0435\u0440 \u043c\u0435\u0442\u043e\u0434 <code>react_component<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0438\u043c\u044f React, \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u043d\u0435\u0433\u043e.  <\/p>\n<pre><code class=\"html\">&lt;%# app\/views\/records\/index.html.erb %&gt;  &lt;%= react_component 'Records', { data: @records } %&gt; <\/code><\/pre>\n<p>  \u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0447\u0442\u043e \u044d\u0442\u043e\u0442 helper \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d react-rails \u0433\u0435\u043c\u043e\u043c, \u0435\u0441\u043b\u0438 \u0432\u044b \u0440\u0435\u0448\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0439 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 React \u043c\u0435\u0442\u043e\u0434, \u044d\u0442\u043e\u0442 \u0445\u0435\u043b\u043f\u0435\u0440 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 <code>localhost:3000\/records<\/code>. \u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e \u0447\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0435 \u0442\u0430\u043a, \u0432\u0441\u0435 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 Records (React \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b). \u041d\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u0432\u043e\u0437\u044c\u043c\u0435\u0442\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 HTML \u0432\u043d\u0443\u0442\u0440\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0447\u0442\u043e \u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u044d\u0442\u043e\u0433\u043e.  <\/p>\n<pre><code class=\"html\">&lt;div data-react-class=&quot;Records&quot; data-react-props=&quot;{...}&quot;&gt; &lt;\/div&gt; <\/code><\/pre>\n<p>  C \u044d\u0442\u043e\u0439 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u043e\u0439 <code>react_ujs<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442, \u043c\u044b \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c React \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u044b \u043f\u043e\u0441\u044b\u043b\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 <code>react_component<\/code>, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 <code>@records<\/code><\/p>\n<p>  \u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u0448 \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0432\u043d\u0443\u0442\u0440\u0438 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>javascripts\/components<\/code> \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b: <code>records.js.coffee<\/code>, \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043d\u0430\u0448 <code>Records<\/code> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442.  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/records.js.coffee    @Records = React.createClass     render: -&gt;       React.DOM.div         className: 'records'         React.DOM.h2           className: 'title'           'Records' <\/code><\/pre>\n<p>  \u041a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0440\u0435\u043d\u0434\u0435\u0440 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0441\u0432\u043e\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0440\u0435\u043d\u0434\u0435\u0440 \u043c\u0435\u0442\u043e\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 <code>ReactComponent<\/code>, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043a\u043e\u0433\u0434\u0430 React \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0440\u0435-\u0440\u0435\u043d\u0434\u0435\u0440 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u044f\u0442\u0441\u044f \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e.<\/p>\n<p>  \u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435. \u0412 \u0434\u0440\u0443\u0433\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>ReactComponents<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 \u0440\u0435\u043d\u0434\u0435\u0440 \u043c\u0435\u0442\u043e\u0434\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e JSX \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430.<br \/>  \u042d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442 \u043a\u043e\u0434\u0443 \u0432\u044b\u0448\u0435:  <\/p>\n<pre><code class=\"coffeescript\"> render: -&gt;  `&lt;div className=&quot;records&quot;&gt;    &lt;h2 className=&quot;title&quot;&gt; Records &lt;\/h2&gt;  &lt;\/div&gt;` <\/code><\/pre>\n<p>  \u041b\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u043c\u0435\u043d\u044f, \u043a\u043e\u0433\u0434\u0430 \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0441 CoffeeScript, \u044f \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>React.DOM<\/code> \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 JSX&#8217;\u0443 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d \u043a \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435, \u043a\u0430\u043a \u0432 HAML \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0435\u0441\u043b\u0438 \u0432\u044b \u043f\u0440\u043e\u0431\u0443\u0435\u0442\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c React \u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441 ERB, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 ERB \u043a\u043e\u0434 \u0438 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 JSX.<\/p>\n<p>  \u041e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/i.imgur.com\/jrehS5B.png\" alt=\"image\"\/><\/p>\n<p>  \u041e\u0442\u043b\u0438\u0447\u043d\u043e. \u041c\u044b \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043b\u0438 \u043d\u0430\u0448 \u043f\u0435\u0440\u0432\u044b\u0439 React \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442. \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u043d\u0430\u0448\u0438 \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440 \u043c\u0435\u0442\u043e\u0434 React \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043b\u044f \u043e\u0431\u043c\u0435\u043d\u0430 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 \u0447\u0442\u043e \u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c \u043d\u0443\u0436\u0435\u043d \u0440\u0435-\u0440\u0435\u043d\u0434\u0435\u0440 \u0438\u043b\u0438 \u043d\u0435\u0442. \u041d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0441 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438.  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/records.js.coffee  @Records = React.createClass   getInitialState: -&gt;     records: @props.data   getDefaultProps: -&gt;     records: []   render: -&gt;       ... <\/code><\/pre>\n<p>  \u041c\u0435\u0442\u043e\u0434 <code>getDefaultProps<\/code> \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0433\u0434\u0430 \u0438\u043d\u0441\u0442\u0430\u043d\u0446\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0438 \u043c\u0435\u0442\u043e\u0434 <code>getInitialState<\/code> \u0431\u0443\u0434\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430\u0448\u0438\u0448 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u0432\u043e\u043e\u0431\u0449\u0435 \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c records \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0430\u0448\u0435\u0433\u043e Rails view.<\/p>\n<p>  \u041f\u043e\u0445\u043e\u0436\u0435 \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0445\u0435\u043b\u043f\u0435\u0440 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u0442\u0440\u043e\u043a, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 <code>coffee<\/code> \u0444\u0430\u0439\u043b\u043e\u0432 \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 <code>utils.js.coffee<\/code> \u0444\u0430\u0439\u043b \u0432 <code>javascripts\/<\/code> \u0441 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u043e\u043c:  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/utils.js.coffee    @amountFormat = (amount) -&gt;     '$ ' + Number(amount).toLocaleString() <\/code><\/pre>\n<p>  \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 Record \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u043a\u0430\u0436\u0434\u0443\u044e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c, \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b <code>record.js.coffee<\/code> \u0432 <code>javascripts\/components<\/code> \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0438 \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/record.js.coffee    @Record = React.createClass     render: -&gt;       React.DOM.tr null,         React.DOM.td null, @props.record.date         React.DOM.td null, @props.record.title         React.DOM.td null, amountFormat(@props.record.amount) <\/code><\/pre>\n<p>  Record \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c\u0441\u044f \u0432 \u043a\u043e\u043b\u043e\u043d\u043a\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0439 \u043a\u043b\u0435\u0442\u043a\u0443 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 \u0437\u0430\u043f\u0438\u0441\u0438. \u041d\u0435 \u0432\u043e\u043b\u043d\u0443\u0439\u0442\u0435\u0441\u044c \u043d\u0430 \u0441\u0447\u0435\u0442 \u044d\u0442\u0438\u0445 <code>null<\/code> \u0432 <code>React.DOM.*<\/code> \u0432\u044b\u0437\u043e\u0432\u0430\u0445, \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u0447\u0442\u043e \u043c\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c.\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u0440\u0435\u043d\u0434\u0435\u0440 \u043c\u0435\u0442\u043e\u0434 \u0432\u043d\u0443\u0442\u0440\u0438 Records \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0441 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u0434\u043e\u043c:  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/records.js.coffee    @Records = React.createClass     ...     render: -&gt;       React.DOM.div         className: 'records'         React.DOM.h2           className: 'title'           'Records'         React.DOM.table           className: 'table table-bordered'           React.DOM.thead null,             React.DOM.tr null,               React.DOM.th null, 'Date'               React.DOM.th null, 'Title'               React.DOM.th null, 'Amount'           React.DOM.tbody null,             for record in @state.records               React.createElement Record, key: record.id, record: record <\/code><\/pre>\n<p>  \u0412\u044b \u0432\u0438\u0434\u0435\u043b\u0438 \u0447\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e? \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u0445\u0435\u0434\u0435\u0440\u043e\u043c \u0438 \u0442\u0435\u043b\u043e\u043c \u0432\u043d\u0443\u0442\u0440\u0438. \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 Record \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u0438. \u0418\u043d\u0430\u0447\u0435 \u0433\u043e\u0432\u043e\u0440\u044f, \u043c\u044b \u0432\u043b\u043e\u0436\u0438\u043b\u0438 build-in\/custom React \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u041a\u0440\u0443\u0442\u043e. \u043f\u0440\u0430\u0432\u0434\u0430?<\/p>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u0432 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 records) \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043a\u043b\u044e\u0447 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u0433\u0435\u043d\u0438\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0435\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0438\u0442\u0430\u043a React \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0448\u0435\u0433\u043e UI(\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430) \u044d\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c<br \/>  \u043a\u043b\u044e\u0447: <code>record.id<\/code> \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u044c\u044e \u043a\u043e\u0433\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u043c Record \u044d\u043b\u0435\u043c\u0435\u043d\u0442. \u0415\u0441\u043b\u0438 \u043c\u044b \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442\u0435\u043c \u044d\u0442\u043e, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 \u0432 \u043d\u0430\u0448\u0435\u0439 JS \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 (\u0438 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u0432 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u043c \u0431\u0443\u0434\u0443\u0449\u0435\u043c, \u0438\u043d\u043e\u0433\u0434\u0430, \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0433\u043e\u043b\u043e\u0432\u043d\u0443\u044e \u0431\u043e\u043b\u044c).<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/i.imgur.com\/vETiEeFg.png\" alt=\"image\"\/><\/p>\n<p>  \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434 \u044d\u0442\u043e\u0439 \u0441\u0435\u043a\u0446\u0438\u0438 <a href=\"https:\/\/github.com\/fervisa\/accounts-react-rails\/tree\/bf1d80cf3d23a9a5e4aa48c86368262b7a7bd809\">\u0442\u0443\u0442<\/a> \u0438\u043b\u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/fervisa\/accounts-react-rails\/commit\/bf1d80cf3d23a9a5e4aa48c86368262b7a7bd809\">\u0438\u0437\u043c\u0435\u043d\u0438\u044f<\/a> \u0441\u0435\u043a\u0446\u0438\u0438.<\/p>\n<h1>\u0421\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c\u0438 \u0438 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438: \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 Records<\/h1>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0442\u0430\u043a\u0436\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u0437\u0434\u043e\u0440\u043e\u0432\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0444\u043e\u0440\u043c\u0443 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u044d\u0442\u0443 \u0444\u0438\u0447\u0443 \u0432 \u043d\u0430\u0448\u0435 React\/Rails \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f (<code>create method<\/code>) \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 (\u043d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u043f\u0440\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <code>_strongparams<\/code> )  <\/p>\n<pre><code class=\"ruby\">class RecordsController &lt; ApplicationController     ...      def create       @record = Record.new(record_params)        if @record.save         render json: @record       else         render json: @record.errors, status: :unprocessable_entity       end     end      private        def record_params         params.require(:record).permit(:title, :amount, :date)       end   end <\/code><\/pre>\n<p>  \u0414\u0430\u043b\u044c\u0448\u0435, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c React \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438. \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u0432\u043e\u0435 \u0441\u043e\u0431\u0441\u0432\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0447\u0442\u043e \u0431\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u0430\u0442\u0443 (date) \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a (title) \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e (amount).  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/record_form.js.coffee    @RecordForm = React.createClass     getInitialState: -&gt;       title: ''       date: ''       amount: ''     render: -&gt;       React.DOM.form         className: 'form-inline'         React.DOM.div           className: 'form-group'           React.DOM.input             type: 'text'             className: 'form-control'             placeholder: 'Date'             name: 'date'             value: @state.date             onChange: @handleChange         React.DOM.div           className: 'form-group'           React.DOM.input             type: 'text'             className: 'form-control'             placeholder: 'Title'             name: 'title'             value: @state.title             onChange: @handleChange         React.DOM.div           className: 'form-group'           React.DOM.input             type: 'number'             className: 'form-control'             placeholder: 'Amount'             name: 'amount'             value: @state.amount             onChange: @handleChange         React.DOM.button           type: 'submit'           className: 'btn btn-primary'           disabled: !@valid()           'Create record' <\/code><\/pre>\n<p>  \u041d\u0438\u0447\u0435\u0433\u043e \u043a\u0440\u0435\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e, \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043d\u043b\u0430\u0439\u043d \u0444\u043e\u0440\u043c\u0430 \u0431\u0443\u0442\u0441\u0442\u0440\u0430\u043f\u0430. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043a\u0430\u043a \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u043d\u043f\u0443\u0442\u043e\u0432(input&#8217;s), <code>onChange<\/code> \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u044f\u0435\u0442 \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u0432\u044b\u0437\u0432\u0430\u043d \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043b\u0430\u0432\u0438\u0448\u0438, \u043c\u0435\u0442\u043e\u0434 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u0447\u0438\u043a <code>handleChange<\/code> \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430, \u043a\u0430\u043a\u043e\u0439 \u0438\u043d\u043f\u0443\u0442 \u0432\u044b\u0437\u0432\u0430\u043b \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u043b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<br \/>  <code># app\/assets\/javascripts\/components\/record_form.js.coffee<\/p>\n<p>  @RecordForm = React.createClass<br \/>   ...<br \/>   handleChange: (e) -&gt;<br \/>   name = e.target.name<br \/>   @setState &quot;#{ name }&quot;: e.target.value<br \/>  <\/code><br \/>  \u041c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 \u0441\u0442\u0440\u043e\u043a \u0434\u043b\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u043a\u0442\u0430 \u043a\u043b\u044e\u0447\u0435\u0439 \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u044b\u0445 <code>@setState title: e.target.value <\/code> \u043a\u043e\u0433\u0434\u0430 \u0438\u043c\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 title. \u041d\u043e \u043f\u043e\u0447\u0435\u043c\u0443 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>@setState<\/code>? \u041f\u043e\u0447\u0435\u043c\u0443 \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0436\u0435\u043b\u0430\u0435\u043c\u043e\u0435\u044b\u0445 &lt;co \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432  <a href=\"https:\/\/habrahabr.ru\/users\/state\/\" class=\"user_link\">state<\/a> \u043a\u0430\u043a \u043c\u044b \u043e\u0431\u044b\u0447\u043d\u043e \u0434\u0435\u043b\u0430\u0435\u043c \u0432 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043dde&gt;JS \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445? \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>@setState<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c 2 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u044d\u0442\u043e:  <\/p>\n<ol>\n<li> \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f<\/li>\n<li> \u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c UI \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443\/\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f<\/li>\n<\/ol>\n<p>  \u041e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u044d\u0442\u0443 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438, \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043a\u043e\u043d\u0446\u0435 \u0440\u0435\u043d\u0434\u0435\u0440 \u043c\u0435\u0442\u043e\u0434\u0430  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/record_form.js.coffee  @RecordForm = React.createClass   ...   render: -&gt;     ...     React.DOM.form       ...       React.DOM.button         type: 'submit'         className: 'btn btn-primary'         disabled: !@valid()         'Create record' <\/code><\/pre>\n<p>  \u041c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 <code>disabled<\/code> \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c <code>!@valid()<\/code>, \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u044f \u0447\u0442\u043e \u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c valid \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043e\u0446\u0435\u043d\u043a\u0438, \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b.  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/record_form.js.coffee    @RecordForm = React.createClass     ...     valid: -&gt;       @state.title && @state.date && @state.amount <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u0443\u0435\u043c <code>@state<\/code> \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u0441\u043d\u043e\u0432\u0430 \u043f\u0443\u0441\u0442\u044b\u043c\u0438 \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f, <code>Create record<\/code> \u043a\u043d\u043e\u043f\u043a\u0430 \u0432\u043a\u043b\/\u0432\u044b\u043a\u043b \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/i.imgur.com\/EuPQ64m.png\" alt=\"image\"\/><\/p>\n<p>  \u0421\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u0448 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0438 \u0444\u043e\u0440\u043c\u0430 \u043d\u0430 \u043c\u0435\u0441\u0442\u0435. \u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u0447\u0442\u043e \u0431\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0430\u0448\u0443 \u043d\u043e\u0432\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0444\u043e\u0440\u043c\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u0414\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0430 <code>onSubmit<\/code> \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043d\u0430\u0448\u0435\u0439 \u0444\u043e\u0440\u043c\u044b \u0438 \u043d\u043e\u0432\u044b\u0439 <code>handleSubmit<\/code> \u043c\u0435\u0442\u043e\u0434 (\u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u043c\u044b \u0434\u0435\u043b\u0430\u043b\u0438 \u0441 <code>onChange<\/code> \u0441\u043e\u0431\u044b\u0442\u0438\u0435\u043c ).  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/record_form.js.coffee    @RecordForm = React.createClass     ...     handleSubmit: (e) -&gt;       e.preventDefault()       $.post '', { record: @state }, (data) =&gt;         @props.handleNewRecord data         @setState @getInitialState()       , 'JSON'      render: -&gt;       React.DOM.form         className: 'form-inline'         onSubmit: @handleSubmit       ... <\/code><\/pre>\n<p>  \u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u043e:  <\/p>\n<ol>\n<li> \u041f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0444\u043e\u0440\u043c\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 <\/li>\n<li> POST \u043d\u043e\u0432\u043e\u0439 record \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e URL <\/li>\n<li> \u0423\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u043a\u043e\u043b\u043b\u0431\u0435\u043a<\/li>\n<\/ol>\n<p>  \u0423\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u043a\u043e\u043b\u043b\u0431\u0435\u043a \u2014 \u044d\u0442\u043e \u043a\u043b\u044e\u0447 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u043a\u0442\u043e \u0442\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u043e\u0431 \u044d\u0442\u043e\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438, \u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u0412\u044b \u043f\u043e\u043c\u043d\u0438\u0442\u0435 \u043a\u043e\u0433\u0434\u0430 \u044f \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u043b \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u0447\u0435\u0440\u0435\u0437 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 (\u0438\u043b\u0438 <code>@props<\/code>)? \u0422\u0430\u043a \u0432\u043e\u0442, \u0442\u0430\u043a \u0438 \u0435\u0441\u0442\u044c. \u041d\u0430\u0448 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043d\u0430\u0437\u0430\u0434 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 <code>@props.handleNewRecord<\/code> \u0441\u043e\u043e\u0431\u0449\u0430\u044f \u043f\u0440\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<p>  \u041a\u0430\u043a \u0432\u044b \u043c\u043e\u0433\u043b\u0438 \u0434\u043e\u0433\u0430\u0434\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u0430\u0448 <code>RecordForm<\/code> \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c <code>handleNewRecord<\/code> \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441 \u0441\u0441\u044b\u043b\u044b\u043a\u043e\u0439 \u043d\u0430 \u043c\u0435\u0442\u043e\u0434 \u0432 \u043d\u0435\u043c, \u0447\u0442\u043e \u0442\u043e \u0432\u0440\u043e\u0434\u0435 <code>React.createElement RecordForm<\/code>, <code>handleNewRecord: @addRecord<\/code>. \u041d\u0443, \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 Records \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u00ab\u0432\u0435\u0437\u0434\u0435\u00bb \u043a\u0430\u043a \u044d\u0442\u043e \u0438\u043c\u0435\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0438\u0437 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u044d\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441 \u043d\u043e\u0432\u043e\u0439 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u044c\u044e<br \/>  \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 <code>addRecord<\/code> \u043c\u0435\u0442\u043e\u0434 \u0432\u043d\u0443\u0442\u0440\u0438 <code>records.js.coffee<\/code> \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e <code>RecordForm<\/code> \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0441\u043b\u0435 h2 title (\u0432\u043d\u0443\u0442\u0440\u0438 \u0440\u0435\u043d\u0434\u0435\u0440 \u043c\u0435\u0442\u043e\u0434\u0430).  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/records.js.coffee    @Records = React.createClass     ...     addRecord: (record) -&gt;       records = @state.records.slice()       records.push record       @setState records: records     render: -&gt;       React.DOM.div         className: 'records'         React.DOM.h2           className: 'title'           'Records'         React.createElement RecordForm, handleNewRecord: @addRecord         React.DOM.hr null <\/code><\/pre>\n<p>  \u041e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0444\u043e\u0440\u043c\u0443 \u0441 \u043d\u043e\u0432\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u044c\u044e, \u043a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u043f\u043e <code>Create record<\/code> \u043d\u0435 \u0443\u0434\u0438\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0437\u0430\u043f\u0438\u0441\u044c \u0431\u044b\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0437\u0430\u043c\u0435\u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0438 \u0444\u043e\u0440\u043c\u0430 \u0441\u0442\u0430\u043b\u0430 \u043f\u0443\u0441\u0442\u043e\u0439 \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f. \u041f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u043e\u0441\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435, \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0431\u0435\u043a\u044d\u043d\u0434 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043b\u0441\u044f \u043d\u043e\u0432\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438<br \/>  <img decoding=\"async\" src=\"https:\/\/i.imgur.com\/635Wuv7.png\" alt=\"image\"\/><\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0439 JS \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0432\u043c\u0435\u0441\u0442\u0435 c React (<b>\u0430\u043d\u0433\u0443\u043b\u0430\u0440<\/b> \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440) \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0435 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0444\u0438\u0447\u0438, \u0442\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u043c\u0435\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u0430\u0448 POST \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0435 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 CSRF \u0442\u043e\u043a\u0435\u043d \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0439 Rails, \u0438\u0442\u0430\u043a, \u043f\u043e\u0447\u0435\u043c\u0443 \u043c\u044b \u043d\u0435 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c \u0441 \u044d\u0442\u0438\u043c \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c? \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>jquery<\/code> \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043d\u0430\u0448\u0438\u043c \u0431\u0435\u043a\u044d\u043d\u0434\u043e\u043c \u0438 <code>Rails jquery_ujs<\/code> \u043d\u0435\u043d\u0430\u0432\u044f\u0437\u0447\u0438\u0432\u044b\u0439 \u0434\u0440\u0430\u0439\u0432\u0435\u0440, \u0431\u0443\u0434\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0432 \u0441\u0435\u0431\u044f \u043c\u0430\u0440\u043a\u0435\u0440 CSRF \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u043d\u0430\u0448\u0435\u043c AJAX \u0437\u0430\u043f\u0440\u043e\u0441\u0435. \u041a\u0440\u0443\u0442\u043e.<\/p>\n<p>  \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u043e\u0434\u0430 \u0432 <a href=\"https:\/\/github.com\/fervisa\/accounts-react-rails\/tree\/f4708e19f8be929471bc0c8c2bda93f36b9a7f23\">\u044d\u0442\u043e\u0439<\/a> \u0441\u0435\u043a\u0446\u0438\u0438, \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c <a href=\"https:\/\/github.com\/fervisa\/accounts-react-rails\/commit\/f4708e19f8be929471bc0c8c2bda93f36b9a7f23\">\u0442\u0443\u0442<\/a><\/p>\n<h1>\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432<\/h1>\n<p>  \u0427\u0435\u0433\u043e \u0431\u044b \u0445\u043e\u0442\u0435\u043b\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0435\u0437 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 (\u0445\u043e\u0440\u043e\u0448\u0438\u0445) \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439? \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u043e\u043a\u0441\u043e\u0432 \u043d\u0430\u0432\u0435\u0440\u0445\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u043e\u043a\u043d\u0430 \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439. \u041c\u044b \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u043c \u0434\u043b\u044f \u0431\u043e\u043a\u0441\u043e\u0432 3 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: \u0421\u0443\u043c\u043c\u0430\u0440\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u0440\u0435\u0434\u0438\u0442\u043e\u0432, \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e\u0435 \u043a\u043e\u043b-\u0432\u043e \u0434\u0435\u0431\u0435\u0442\u0430 \u0438 \u0431\u0430\u043b\u0430\u043d\u0441.<br \/>  \u042d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0442\u0440\u0435\u043c\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u0438\u043b\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a?<\/p>\n<p>  \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 <code>AmountBox<\/code> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438: \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u0435\u043a\u0441\u0442 \u0438 \u0442\u0438\u043f. \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0432\u044b\u0437\u043e\u0432\u0435\u0442 <code>amount_box.js.coffee<\/code> \u0438\u0437 <code>javascripts\/components\/<\/code> \u0438 \u0432\u0441\u0442\u0430\u0432\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/amount_box.js.coffee   @AmountBox = React.createClass    render: -&gt;      React.DOM.div        className: 'col-md-4'        React.DOM.div          className: &quot;panel panel-#{ @props.type }&quot;          React.DOM.div            className: 'panel-heading'            @props.text          React.DOM.div            className: 'panel-body'            amountFormat(@props.amount) <\/code><\/pre>\n<p>  \u041c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0431\u0443\u0442\u0441\u0442\u0440\u0430\u043f \u043f\u0430\u043d\u0435\u043b\u044c, \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0432 \u00abblocky\u00bb \u043c\u0435\u0442\u043e\u0434\u0435 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0446\u0432\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 \u0442\u0438\u043f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.<br \/>  \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u0435\u043c \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0435 \u0438 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432\u044b\u0437\u0432\u0430\u043d\u043d\u044b\u0445 <code>amountFormat<\/code> \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0447\u0438\u0442\u0430\u044e\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442 \u044d\u0442\u043e \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0432\u0430\u043b\u044e\u0442.<\/p>\n<p>  \u0412 \u0437\u0430\u043a\u0430\u0437\u0435 \u0435\u0441\u0442\u044c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 3 \u0440\u0430\u0437\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e (main) \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0440\u043e\u0442 \u043c\u0435\u0442\u043e\u0434\u043e\u0432. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445 \u043e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 <code>Record<\/code> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438 \u0434\u043e\u0431\u0430\u0432\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434:  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/records.js.coffee    @Records = React.createClass     ...     credits: -&gt;       credits = @state.records.filter (val) -&gt; val.amount &gt;= 0       credits.reduce ((prev, curr) -&gt;         prev + parseFloat(curr.amount)       ), 0     debits: -&gt;       debits = @state.records.filter (val) -&gt; val.amount &lt; 0       debits.reduce ((prev, curr) -&gt;         prev + parseFloat(curr.amount)       ), 0     balance: -&gt;       @debits() + @credits()     ... <\/code><\/pre>\n<p>  \u0421\u0443\u043c\u043c\u0430 <code>credits<\/code> \u0432\u0441\u0435\u0445 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0441 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u0435 0. C\u0443\u043c\u043c\u0430 \u0434\u0435\u0431\u0435\u0442\u043e\u0432 \u0432\u0441\u0435\u0445 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0435\u043d\u044c\u0448\u0435 0 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0431\u0430\u043b\u0430\u043d\u0441\u0430. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0432 \u043d\u0443\u0436\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432. \u041d\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c <code>AmountBox<\/code> \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432\u043d\u0443\u0442\u0440\u0438, \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 (\u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0448\u0435 <code>RecordForm<\/code> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430)  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/records.js.coffee    @Records = React.createClass     ...     render: -&gt;       React.DOM.div         className: 'records'         React.DOM.h2           className: 'title'           'Records'         React.DOM.div           className: 'row'           React.createElement AmountBox, type: 'success', amount: @credits(), text: 'Credit'           React.createElement AmountBox, type: 'danger', amount: @debits(), text: 'Debit'           React.createElement AmountBox, type: 'info', amount: @balance(), text: 'Balance'         React.createElement RecordForm, handleNewRecord: @addRecord     ... <\/code><\/pre>\n<p>  \u041c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438 \u0441 \u044d\u0442\u043e\u0439 \u0444\u0438\u0447\u0435\u0439! \u041e\u0431\u043d\u043e\u0432\u0438\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440. \u0412\u044b \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0443\u0432\u0438\u0434\u0435\u043b\u0438 3 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u044b\u0445 \u0431\u043e\u043a\u0441\u0430, \u0441\u0443\u043c\u043c\u044b \u043c\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u043b\u0438 \u0440\u0430\u043d\u044c\u0448\u0435. \u041d\u043e \u043f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435! \u0415\u0441\u0442\u044c \u0435\u0449\u0435! \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u0438 \u0443\u0432\u0438\u0434\u0438\u043c \u043c\u0430\u0433\u0438\u044e \u0432 \u0440\u0430\u0431\u043e\u0442\u0435.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/i.imgur.com\/YWEcQHh.png\" alt=\"image\"\/><\/p>\n<p>  \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 <a href=\"https:\/\/github.com\/fervisa\/accounts-react-rails\/tree\/8d6f0a4fb62f2a9abd5d34d502461388863302cb\">\u043a\u043e\u0434\u0430<\/a> <br \/>  \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f <a href=\"https:\/\/github.com\/fervisa\/accounts-react-rails\/commit\/8d6f0a4fb62f2a9abd5d34d502461388863302cb\">\u0442\u0443\u0442<\/a><\/p>\n<h1>setState\/replaceState: \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0435\u0439<\/h1>\n<p>  \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0444\u0438\u0447\u0430 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043f\u0438\u0441\u043a\u0435 \u2014 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u0435\u043d \u043d\u043e\u0432\u0430\u044f \u044d\u043a\u0448\u043d \u043a\u043e\u043b\u043e\u043d\u043a\u0430 \u0432 \u043d\u0430\u0448\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0437\u0430\u043f\u0438\u0441\u0435\u0439. \u042d\u0442\u0430 \u043a\u043e\u043b\u043e\u043d\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c Delete \u043a\u043d\u043e\u043f\u043a\u0443 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438, \u0441\u0438\u043c\u043f\u0430\u0442\u0438\u0447\u043d\u044b\u0439 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 UI. \u041a\u0430\u043a \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u0432 \u043d\u0430\u0448\u0435\u043c Rails \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435.  <\/p>\n<pre><code class=\"ruby\"># app\/controllers\/records_controller.rb   class RecordsController &lt; ApplicationController    ...     def destroy      @record = Record.find(params[:id])      @record.destroy      head :no_content    end     ...  end  <\/code><\/pre>\n<p>  \u042d\u0442\u043e \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0444\u0438\u0447\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u0432\u0430\u0448\u0438 <code>Records React<\/code> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438 \u0434\u043e\u0431\u0430\u0432\u0442\u0435 \u0432 \u044d\u043a\u0448\u0435\u043d\u044b \u043a\u043e\u043b\u043e\u043d\u043a\u0443 \u0441\u043f\u0440\u0430\u0432\u0430 \u0432 \u0445\u0435\u0430\u0434\u0435\u0440 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/records.js.coffee    @Records = React.createClass     ...     render: -&gt;       ...       # almost at the bottom of the render method       React.DOM.table         React.DOM.thead null,           React.DOM.tr null,             React.DOM.th null, 'Date'             React.DOM.th null, 'Title'             React.DOM.th null, 'Amount'             React.DOM.th null, 'Actions'         React.DOM.tbody null,           for record in @state.records             React.createElement Record, key: record.id, record: record <\/code><\/pre>\n<p>  \u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u043e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 Record \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438 \u0434\u043e\u0431\u0430\u0432\u0442\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u043a\u043e\u043b\u043e\u043d\u043a\u0443 \u0441 Delete \u0441\u0441\u044b\u043b\u043a\u043e\u0439  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/record.js.coffee      @Record = React.createClass     render: -&gt;     React.DOM.tr null,      React.DOM.td null, @props.record.date      React.DOM.td null, @props.record.title      React.DOM.td null, amountFormat(@props.record.amount)      React.DOM.td null,        React.DOM.a          className: 'btn btn-danger'          'Delete' <\/code><\/pre>\n<p>  \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u0432\u0430\u0448 \u0444\u0430\u0439\u043b, \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0438 \u041c\u044b \u0438\u043c\u0435\u0435\u043c \u043d\u0435\u0440\u0430\u0431\u043e\u0447\u0443\u044e \u043a\u043d\u043e\u043f\u043a\u0443 \u0431\u0435\u0437 \u043a\u0430\u043a\u0438\u0445 \u043b\u0438\u0431\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u044b\u0445 \u043a \u043d\u0435\u0439.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/i.imgur.com\/JV1KVNK.png\" alt=\"image\"\/><\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u041a\u0430\u043a \u043c\u044b \u0443\u0437\u043d\u0430\u043b\u0438 \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e <code>RecordForm<\/code> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u043f\u0438\u0441\u043e\u043a:  <\/p>\n<ol>\n<li> \u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0432\u043d\u0443\u0442\u0438 \u043f\u043e\u0442\u043e\u043c\u043a\u0430 Record \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 (onClick) <\/li>\n<li> \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u044d\u043a\u0448\u043d (\u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c DELETE \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435) <\/li>\n<li> \u0423\u0432\u0435\u0434\u043e\u043c\u0438\u0442\u044c Records \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043e\u0431 \u044d\u0442\u043e\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 (\u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \/ \u043f\u0440\u0438\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438)<\/li>\n<li> \u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 Record \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 <\/li>\n<\/ol>\n<p>  \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0448\u0430\u0433\u0430 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a <code>OnClick<\/code> \u043a <code>Record<\/code>\u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f <code>onSubmit<\/code> \u043a <code>RecordForm<\/code> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0437\u0430\u043f\u0438\u0441\u0435\u0439. \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e \u0434\u043b\u044f \u043d\u0430\u0441, React \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043e\u0431\u0449\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0432 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0438\u0434\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u0435\u0441\u043f\u043e\u043a\u043e\u0438\u0442\u044c\u0441\u044f \u043e \u043a\u0440\u043e\u0441\u0441-\u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u043e\u0439 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 (\u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u043f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u0439 <a href=\"http:\/\/facebook.github.io\/react\/docs\/events.html#supported-events\">\u0437\u0434\u0435\u0441\u044c<\/a> ).<\/p>\n<p>  \u0421\u043d\u043e\u0432\u0430 \u043e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0437\u0430\u043f\u0438\u0441\u0438, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <code>handleDelete<\/code> \u0438 <code>OnClick<\/code> \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043d\u0430\u0448\u0435\u0439 \u00ab\u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439\u00bb \u043a\u043d\u043e\u043f\u043a\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/record.js.coffee    @Record = React.createClass     handleDelete: (e) -&gt;       e.preventDefault()       # yeah... jQuery doesn't have a $.delete shortcut method       $.ajax         method: 'DELETE'         url: &quot;\/records\/#{ @props.record.id }&quot;         dataType: 'JSON'         success: () =&gt;           @props.handleDeleteRecord @props.record     render: -&gt;       React.DOM.tr null,         React.DOM.td null, @props.record.date         React.DOM.td null, @props.record.title         React.DOM.td null, amountFormat(@props.record.amount)         React.DOM.td null,           React.DOM.a             className: 'btn btn-danger'             onClick: @handleDelete             'Delete' <\/code><\/pre>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043a\u043b\u0438\u043a \u043f\u043e \u043a\u043d\u043e\u043f\u043a\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c <code>handleDelete<\/code> \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 AJAX \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443<br \/>  \u0447\u0442\u043e\u0431\u044b \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0430 \u0431\u0435\u043a\u044d\u043d\u0434\u0435 \u0438 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0438\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u043f\u0440\u043e \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 <code>handleDeleteRecord<\/code> \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0447\u0435\u0440\u0435\u0437 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0433\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 Record \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435,<br \/>  \u0447\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>handleDeleteRecord<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0432 \u043f\u0440\u0435\u0434\u043a\u0430\u0445:  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/records.js.coffee  @Records = React.createClass   ...   deleteRecord: (record) -&gt;     records = @state.records.slice()     index = records.indexOf record     records.splice index, 1     @replaceState records: records   render: -&gt;     ...     # almost at the bottom of the render method     React.DOM.table       React.DOM.thead null,         React.DOM.tr null,           React.DOM.th null, 'Date'           React.DOM.th null, 'Title'           React.DOM.th null, 'Amount'           React.DOM.th null, 'Actions'       React.DOM.tbody null,         for record in @state.records           React.createElement Record, key: record.id, record: record, handleDeleteRecord: @deleteRecord <\/code><\/pre>\n<p>  \u0412 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043d\u0430\u0448 <code>deleteRecord<\/code> \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0435\u0439, \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0438\u0441\u043a\u0430 \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u0437\u0430\u043f\u0438\u0441\u0438 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0443\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c. \u043c\u0438\u043b\u044b\u0439 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 JS \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439.<\/p>\n<p>  \u041c\u044b \u0432\u0432\u0435\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c <code>replaceState<\/code> \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 <code>setState<\/code> \u0438 <code>replaceState<\/code> \u044d\u0442\u043e \u0442\u043e \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043e\u0434\u0438\u043d \u043a\u043b\u044e\u0447 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0441 \u043b\u044e\u0431\u044b\u043c \u043d\u043e\u0432\u044b\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u043e\u0441\u044b\u043b\u0430\u0435\u043c.<\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0431\u0438\u0442\u0430 \u043a\u043e\u0434\u0430 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u043e\u043a\u043d\u043e \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0438 \u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u044c, \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 \u0434\u0432\u0435 \u0432\u0435\u0449\u0438:  <\/p>\n<ol>\n<li> \u0417\u0430\u043f\u0438\u0441\u044c \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u0440\u043e\u043f\u0430\u0441\u0442\u044c \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b <\/li>\n<li> \u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u043e\u043b-\u0432\u043e (\u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043d\u0443\u0436\u0435\u043d \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u0434).<\/li>\n<\/ol>\n<p>  <img decoding=\"async\" src=\"https:\/\/i.imgur.com\/fjoCUYN.png\" alt=\"image\"\/><\/p>\n<p>  \u041c\u044b \u043f\u043e\u0447\u0442\u0438 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438 \u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0444\u0438\u0447\u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 \u0432 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f, \u0432\u0432\u0435\u0441\u0442\u0438 \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e React.<\/p>\n<h1>Refactor: State Helpers<\/h1>\n<p>  \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0444\u0438\u0447\u0430. \u041c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043d\u043e\u043f\u043a\u0443 <code>Edit<\/code> \u043f\u043e\u0441\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 <code>Delete<\/code> \u043a\u043d\u043e\u043f\u043a\u0438 \u0432 \u043d\u0430\u0448\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0443. \u041a\u043e\u0433\u0434\u0430 \u043a\u043b\u0438\u043a\u043d\u0435\u043c \u043f\u043e \u043a\u043d\u043e\u043f\u043a\u0435 <code>Edit<\/code> \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0432\u0441\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u0441\u043e\u0441\u0442\u043e\u043d\u0438\u044f \u00ab\u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f\u00bb \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044f \u0438\u043d\u043b\u0430\u0439\u043d \u0444\u043e\u0440\u043c\u0443, \u0433\u0434\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0435\u0439. \u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u0430\u0447\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0438\u043b\u0438 \u043e\u0442\u043c\u0435\u043d\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043a \u0441\u0442\u0440\u043e\u043a\u0435, \u0437\u0430\u043f\u0438\u0441\u044c \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f.<\/p>\n<p>  \u041a\u0430\u043a \u0432\u044b \u0434\u043e\u0433\u0430\u0434\u0430\u043b\u0438\u0441\u044c \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0433\u043b\u0430\u0432\u044b \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 <code>Record<\/code>. \u042d\u0442\u043e \u0441\u043b\u0443\u0447\u0430\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e React \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. <br \/>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0444\u043b\u0430\u0433 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043c\u0435\u0442\u043e\u0434 handleToggle \u043a record.js.coffee:<\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/record.js.coffee  @Record = React.createClass  getInitialState: -&gt;    edit: false  handleToggle: (e) -&gt;    e.preventDefault()    @setState edit: !@state.edit  ... <\/code><\/pre>\n<p>  \u0424\u043b\u0430\u0433 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d, \u0438 <code>handleToggle<\/code> \u0438\u0437\u043c\u0435\u043d\u0438\u0442 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442 \u043b\u043e\u0436\u043d\u043e\u0433\u043e \u043a \u0438\u0441\u0442\u0438\u043d\u043d\u043e\u043c\u0443, \u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u043d\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c <code>handleToggle<\/code> \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c <code>OnClick<\/code> \u0441\u043e\u0431\u044b\u0442\u0438\u0435.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u0432\u0443\u043c\u044f \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u0447\u0438\u0442\u0430\u0442\u044c\/\u0447\u0438\u0442\u0430\u0442\u044c_\u0438_\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0438\u0445 \u0443\u0441\u043b\u043e\u0432\u043d\u043e \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e \u0434\u043b\u044f \u043d\u0430\u0441, \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043a\u0430\u043a \u043d\u0430\u0448 \u043c\u0435\u0442\u043e\u0434 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 React \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u043c\u044b \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b \u0441\u043e\u0432\u0435\u0440\u0448\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0432 \u043d\u0435\u043c; \u043c\u044b<br \/>  \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 <code>recordRow<\/code> \u0438 <code>recordForm<\/code> \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u0445 \u0443\u0441\u043b\u043e\u0432\u043d\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f <code>@ state.edit<\/code>.<\/p>\n<p>  \u0423 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 <code>recordRow<\/code>, \u044d\u0442\u043e \u043d\u0430\u0448 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0432 \u043d\u0430\u0448 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <code>recordRow<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434 \u043a \u043d\u0435\u043c\u0443:  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/record.js.coffee  @Record = React.createClass ... recordRow: -&gt;   React.DOM.tr null,     React.DOM.td null, @props.record.date     React.DOM.td null, @props.record.title     React.DOM.td null, amountFormat(@props.record.amount)     React.DOM.td null,       React.DOM.a         className: 'btn btn-default'         onClick: @handleToggle         'Edit'       React.DOM.a         className: 'btn btn-danger'         onClick: @handleDelete         'Delete' ... <\/code><\/pre>\n<p>  \u041c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 <code>React.DOM<\/code>. a \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0436\u0434\u0435\u0442 \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u043e\u0442 <code>onClick<\/code> \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 <code>handleToggle<\/code><\/p>\n<p>  \u0414\u0432\u0438\u0433\u0430\u0435\u043c\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f <code>recordForm<\/code> \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043d\u043e \u0441 input \u043f\u043e\u043b\u0435\u043c \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u043b\u0435\u0442\u043a\u0435. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 <code>ref<\/code> \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 input&#8217;o\u0432, \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0438\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438; \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u044d\u0442\u043e\u0442 \u043d\u043e\u0432\u044b\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u0448\u0435\u043c\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0447\u0435\u0440\u0435\u0437<code>@refs:<\/code><\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/record.js.coffee    @Record = React.createClass     ...     recordForm: -&gt;       React.DOM.tr null,         React.DOM.td null,           React.DOM.input             className: 'form-control'             type: 'text'             defaultValue: @props.record.date             ref: 'date'         React.DOM.td null,           React.DOM.input             className: 'form-control'             type: 'text'             defaultValue: @props.record.title             ref: 'title'         React.DOM.td null,           React.DOM.input             className: 'form-control'             type: 'number'             defaultValue: @props.record.amount             ref: 'amount'         React.DOM.td null,           React.DOM.a             className: 'btn btn-default'             onClick: @handleEdit             'Update'           React.DOM.a             className: 'btn btn-danger'             onClick: @handleToggle             'Cancel'     ...  <\/code><\/pre>\n<p>  \u041d\u0435 \u0432\u043e\u043b\u043d\u0443\u0439\u0442\u0435\u0441\u044c. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043c\u043e\u0433 \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u043e \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e html \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441.<br \/>  \u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435. \u041c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>@handleEdit<\/code>, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 <code>Update<\/code>, \u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0434\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0435\u0439.<\/p>\n<p>  \u0417\u0430\u043c\u0435\u0442\u0438\u043b\u0438 \u043b\u0438 \u0432\u044b \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u0432 \u0442\u043e\u043c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f <code>React.DOM.inputs<\/code>? \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>defaultValue<\/code> \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u0431\u044b \u0437\u0430\u0434\u0430\u0442\u044c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0431\u0435\u0437 <code>OnChange<\/code><br \/>  \u0431\u0443\u0434\u0435\u0442 \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435 \u0441\u043e\u0437\u0434\u0430\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f input&#8217;\u043e\u0432.<\/p>\n<p>  \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u0435\u0442\u043e\u0434 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u043a\u043e\u0434\u0443:<\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/record.js.coffee     @Record = React.createClass      ...      render: -&gt;        if @state.edit          @recordForm()        else          @recordRow() <\/code><\/pre>\n<p>  \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c \u0441 \u043d\u043e\u0432\u044b\u043c \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043d\u043e \u043e\u043d\u043e \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/i.imgur.com\/dwNuuXw.png\" alt=\"image\"\/><\/p>\n<p>  \u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0437\u0430\u043f\u0438\u0441\u0435\u0439, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443 Rails:  <\/p>\n<pre><code class=\"ruby\"># app\/controllers\/records_controller.rb  class RecordsController &lt; ApplicationController   ...   def update     @record = Record.find(params[:id])     if @record.update(record_params)       render json: @record     else       render json: @record.errors, status: :unprocessable_entity     end   end   ... end <\/code><\/pre>\n<p>  \u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u0437\u0430\u043f\u0438\u0441\u0438, \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>handleEdit<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c AJAX \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0441 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u0438, \u0442\u043e\u0433\u0434\u0430 \u043e\u043d \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u0442 \u043e\u0431 \u044d\u0442\u043e\u043c \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0432 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0437\u0430\u043f\u0438\u0441\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>handleEditRecord<\/code>, \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d \u0447\u0435\u0440\u0435\u0437 <code> @props<\/code>, \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u043c\u044b \u0434\u0435\u043b\u0430\u043b\u0438 \u044d\u0442\u043e \u0440\u0430\u043d\u044c\u0448\u0435 \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439:  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/record.js.coffee   @Record = React.createClass    ...    handleEdit: (e) -&gt;      e.preventDefault()      data =        title: React.findDOMNode(@refs.title).value        date: React.findDOMNode(@refs.date).value        amount: React.findDOMNode(@refs.amount).value      # jQuery doesn't have a $.put shortcut method either      $.ajax        method: 'PUT'        url: &quot;\/records\/#{ @props.record.id }&quot;        dataType: 'JSON'        data:          record: data        success: (data) =&gt;          @setState edit: false <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b, \u043c\u044b \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b\u0438 \u0438\u0445 \u0447\u0435\u0440\u0435\u0437 <code>React.findDOMNode<\/code> (<code>@ refs.fieldName<\/code>) .value \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0432 \u0438\u0445 \u0434\u043e\u0441\u043b\u043e\u0432\u043d\u043e \u043d\u0430 \u0431\u044d\u043a\u044d\u043d\u0434. \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0432 \u0440\u0435\u0436\u0438\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0443\u0441\u043f\u0435\u0445 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c, \u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u043e, \u0431\u0443\u0434\u0435\u0442 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u0438\u0442\u044c \u043d\u0430\u0441 \u0437\u0430 \u044d\u0442\u043e.<\/p>\n<p>  \u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u043d\u043e \u043d\u0435 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043d\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 Records, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u0435\u0436\u043d\u0438\u0439 record \u0441 \u043d\u043e\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \u043f\u043e\u0442\u043e\u043c\u043a\u0430 record \u0438 \u043f\u0443\u0441\u0442\u044c React \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u0432\u043e\u044e \u043c\u0430\u0433\u0438\u044e. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:  <\/p>\n<pre><code class=\"coffeescript\"># app\/assets\/javascripts\/components\/records.js.coffee    @Records = React.createClass     ...     updateRecord: (record, data) -&gt;       index = @state.records.indexOf record       records = React.addons.update(@state.records, { $splice: [[index, 1, data]] })       @replaceState records: records     ...     render: -&gt;       ...       # almost at the bottom of the render method       React.DOM.table         React.DOM.thead null,           React.DOM.tr null,             React.DOM.th null, 'Date'             React.DOM.th null, 'Title'             React.DOM.th null, 'Amount'             React.DOM.th null, 'Actions'         React.DOM.tbody null,           for record in @state.records             React.createElement Record, key: record.id, record: record, handleDeleteRecord: @deleteRecord, handleEditRecord: @updateRecord <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u043c\u044b \u0443\u0437\u043d\u0430\u043b\u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>React.addons.update<\/code> \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u043c\u0435\u0442\u043e\u0434\u0430\u043c. \u041a\u043e\u043d\u0435\u0447\u043d\u044b\u043c \u0437\u0432\u0435\u043d\u043e\u043c \u043c\u0435\u0436\u0434\u0443 Records \u0438 Record \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <code>@updateRecord<\/code>\u043e\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <code>handleEditRecord<\/code> \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.<\/p>\n<p>  \u041e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u0441\u0432\u043e\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437 \u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438, \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u043a\u0430\u043a \u0431\u043e\u043a\u0441\u044b \u0432 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0441\u043b\u0435\u0434\u044f\u0442 \u0437\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u044c\u044e, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0435.<br \/>  <img decoding=\"async\" src=\"https:\/\/i.imgur.com\/qLPVSlU.png\" alt=\"image\"\/><\/p>\n<p>  \u041c\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438! <br \/>  \u041c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 Rails + React \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u043d\u0443\u043b\u044f!<\/p>\n<p>  \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u043e\u0434\u0430 <a href=\"https:\/\/github.com\/fervisa\/accounts-react-rails\/tree\/1a62dd0e48b31aa55659e0035e754cee1776aa61\">\u0442\u0443\u0442<\/a> \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c <a href=\"https:\/\/github.com\/fervisa\/accounts-react-rails\/commit\/1a62dd0e48b31aa55659e0035e754cee1776aa61\">\u0442\u0443\u0442<\/a><\/p>\n<h1>\u0417\u0430\u0432\u0435\u0440\u0448\u0430\u044e\u0449\u0430\u044f \u043c\u044b\u0441\u043b\u044c: React.js, \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u0430 \u0438 \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c<\/h1>\n<p>  \u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 React \u0438 \u0443\u0437\u043d\u0430\u043b\u0438, \u0447\u0442\u043e \u043e\u043d \u0435\u0434\u0432\u0430 \u0432\u0432\u043e\u0434\u0438\u0442 \u043d\u043e\u0432\u044b\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f. \u042f \u0441\u043b\u044b\u0448\u0430\u043b \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438, \u043a\u0430\u043a \u043b\u044e\u0434\u0438 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 X \u0438\u043b\u0438 Y \u0440\u0430\u043c\u043a\u0438, JavaScript \u0438\u043c\u0435\u0435\u0442 \u043a\u0440\u0443\u0442\u0443\u044e \u043a\u0440\u0438\u0432\u0443\u044e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u0437-\u0437\u0430 \u0432\u0441\u0435\u0445 \u043d\u043e\u0432\u043e-\u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043d\u044f\u0442\u0438\u0439, \u044d\u0442\u043e \u043d\u0435 React \u0441\u043b\u0443\u0447\u0430\u0439; \u043e\u043d \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f JavaScript, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0435\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0432 \u043e\u0441\u0432\u043e\u0435\u043d\u0438\u0438 \u0438 \u043f\u043e\u0437\u043d\u0430\u043d\u0438\u0438. \u041e\u043f\u044f\u0442\u044c \u0436\u0435, \u043e\u0434\u043d\u0430 \u0438\u0437 \u0435\u0433\u043e \u0441\u0438\u043b\u044c\u043d\u044b\u0445 \u0441\u0442\u043e\u0440\u043e\u043d \u044d\u0442\u043e \u0435\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u0430.<\/p>\n<p>  \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0443\u0437\u043d\u0430\u043b\u0438 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435, \u043a\u0430\u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u00ab\u0430\u043a\u0442\u0438\u0432\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0438 \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u043e\u043d \u0438\u0433\u0440\u0430\u0435\u0442 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 CoffeeScript, JQuery, Turbolinks, \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u044e \u0440\u0435\u043b\u044c\u0441\u043e\u0432\u00bb \u0420\u0435\u043b\u044c\u0441-\u043e\u0440\u043a\u0435\u0441\u0442\u0440 \u0442\u0430\u043a \u0441\u043a\u0430\u0437\u0430\u0442\u044c. \u041d\u043e \u044d\u0442\u043e \u043d\u0435 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u0436\u0435\u043b\u0430\u0435\u043c\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 Turbolinks (\u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u0432\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e react_ujs) \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Rails \u0430\u043a\u0442\u0438\u0432\u044b \u0432\u043c\u0435\u0441\u0442\u043e \u0433\u0435\u043c\u0430 react-reils, \u0432\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c JBuilder \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 JSON \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u0432\u043c\u0435\u0441\u0442\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 JSON; \u043e\u0434\u043d\u0430\u043a\u043e \u0432\u044b \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u0435 \u0436\u0435 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b.       <\/p>\n<div class=\"clear\"><\/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:\/\/habrahabr.ru\/post\/281735\/\"> https:\/\/habrahabr.ru\/post\/281735\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       <i>\u041d\u0430 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u0442\u0430\u043a\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u044b \u2014 \u043c\u043e\u0439 \u0432\u043a\u043b\u0430\u0434 \u0432 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435 rails \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430.<\/i><br \/>  <i>\u0414\u0430\u043b\u044c\u0448\u0435 \u0432 \u0442\u0435\u043a\u0441\u0442\u0435 \u0432\u0441\u0435 \u0447\u0442\u043e \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043e \u043a\u0443\u0440\u0441\u0438\u0432\u043e\u043c \u043c\u043e\u0438 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f (\u0442\u0430\u043a\u0438\u0445 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u043c\u043d\u043e\u0433\u043e:) )<\/i><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/7f8\/0c6\/fe0\/7f80c6fe03d73212bc0768490700c3de.png\" alt=\"image\"\/><\/p>\n<p>  <b>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 React.js<\/b><\/p>\n<p>  <b>React.js<\/b> \u044d\u0442\u043e \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u043f\u0430\u0440\u0435\u043d\u044c \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u044b JavaScript \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432, \u043e\u043d \u0441\u0438\u044f\u0435\u0442 \u0441\u0432\u043e\u0435\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u043e\u0439. \u041a\u043e\u0433\u0434\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 <b>MVC<\/b> (Model View Controller) \u043f\u043e\u0434\u0445\u043e\u0434, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043a\u0430\u0437\u0430\u0442\u044c React&#8217;\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e View (\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435) (\u0444\u0430\u043a\u0442 \u2014 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u044e\u0434\u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u0447\u0430\u0441\u0442\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f (V) \u044d\u0442\u0438\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 c \u043f\u043e\u043c\u043e\u0449\u044c\u044e React).<\/p>\n<p>  \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u0440\u0435\u0430\u043a\u0442\u043e\u043c \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u044b \u043d\u0430 2\u0445 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430\u0445 \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438 \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u043b\u043a\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0438\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445. \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0447\u0442\u043e \u0440\u0435\u0431\u044f\u0442\u0430 \u0438\u0437 Facebook \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043e\u0434\u043d\u043e\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0439 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u044f \u0447\u0442\u043e \u043d\u0430\u0448 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441(UI) \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<p>  \u041e\u0434\u043d\u0430 \u0445\u043e\u0440\u043e\u0448\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c React.js \u044d\u0442\u043e \u0442\u043e \u0447\u0442\u043e \u043e\u043d \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043a\u0430\u043a\u0438\u0445-\u043b\u0438\u0431\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0447\u0442\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0435\u043c\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u043e\u0441\u0442\u044c \u0441 \u043b\u044e\u0431\u043e\u0439 js \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439. \u041f\u043e\u043b\u044c\u0437\u0443\u044f\u0441\u044c \u044d\u0442\u0438\u043c, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u044c \u0435\u0433\u043e \u0432 \u043d\u0430\u0448 Rails \u0441\u0442\u0435\u043a \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u00abRails \u043d\u0430 \u0441\u0442\u0435\u0440\u043e\u0438\u0434\u0430\u0445\u00bb.<\/p>\n<h1>\u041c\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h1>\n<p>  \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0433\u0430\u0439\u0434\u0430 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u043d\u0443\u043b\u044f \u0447\u0442\u043e \u0431\u044b \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u041a\u0430\u0436\u0434\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c(<i>\u0434\u0430\u043b\u044c\u0448\u0435, \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0447\u0442\u043e \u0438 Record<\/i>) \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0434\u0430\u0442\u044b, \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430. \u0417\u0430\u043f\u0438\u0441\u044c \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u041a\u0440\u0435\u0434\u0438\u0442(Credit) \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u0441\u0443\u043c\u043c\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0443\u043b\u044f, \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430r \u0434\u0435\u0431\u0435\u0442. \u0412\u043e\u0442 \u043c\u0430\u043a\u0435\u0442 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/3b1\/641\/e13\/3b1641e134a4819b1ba616aa202a05b8.png\" alt=\"image\"\/><\/p>\n<p>  \u0421\u0443\u043c\u043c\u0430\u0440\u043d\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u0435\u0441\u0442\u0438 \u0441\u0435\u0431\u044f \u0442\u0430\u043a:  <\/p>\n<ol>\n<li>\u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u0447\u0435\u0440\u0435\u0437 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u0443\u044e \u0444\u043e\u0440\u043c\u0443, \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 <\/li>\n<li>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u0443\u044e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c <\/li>\n<li>\u041a\u043b\u0438\u043a\u043d\u0443\u0432 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 Delete \u043e\u043d \u0443\u0434\u0430\u043b\u0438\u0442 \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u044e \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b <\/li>\n<li>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u043e\u043a\u0441\u043e\u0432 \u0432 \u0432\u0435\u0440\u0445\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b <\/li>\n<\/ol>\n<h1> \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f React.js \u0432 Rails \u043f\u0440\u043e\u0435\u043a\u0442 <\/h1>\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-278821","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/278821","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=278821"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/278821\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=278821"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=278821"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=278821"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}