{"id":348761,"date":"2023-06-14T09:01:47","date_gmt":"2023-06-14T09:01:47","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=348761"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=348761","title":{"rendered":"<span>RSC \u0441 \u043d\u0443\u043b\u044f. \u0427\u0430\u0441\u0442\u044c 1: \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/jc\/hw\/st\/jchwst6a3nwlxlscnmuw5tdhmry.png\" data-src=\"https:\/\/habrastorage.org\/webt\/jc\/hw\/st\/jchwst6a3nwlxlscnmuw5tdhmry.png\"\/>  <\/p>\n<p>  \u0412 \u044d\u0442\u043e\u043c \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u043c &#171;\u0433\u043b\u0443\u0431\u043e\u043a\u043e\u043c \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0438&#187; (deep dive) \u043c\u044b \u0441 \u043d\u0443\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e <a href=\"https:\/\/github.com\/reactjs\/rfcs\/blob\/main\/text\/0188-server-components.md\" rel=\"nofollow noopener noreferrer\">\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 React<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0442\u0440\u0435\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 (\u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u043f\u043e\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0430).<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2 id=\"serezno-eto-glubokoe-pogruzhenie\">\u0421\u0435\u0440\u044c\u0435\u0437\u043d\u043e, \u044d\u0442\u043e \u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0435 \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0435!<\/h2>\n<p>  <\/p>\n<p>\u042d\u0442\u043e\u0442 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u043d\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 React \u0438\u043b\u0438 \u043a\u0430\u043a \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e RSC, \u0438\u043b\u0438 \u043a\u0430\u043a \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0441 \u0438\u0445 \u043f\u043e\u043c\u043e\u0449\u044c\u044e. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e, \u043e\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u0442 \u0432\u0430\u0441 \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0438\u0445 &#171;\u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0435\u043d\u0438\u044f&#187; \u0441 \u043d\u0443\u043b\u044f.<\/p>\n<p>  <\/p>\n<p><em>\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0434\u043b\u044f \u043b\u044e\u0434\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0438\u0437\u0443\u0447\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0438\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u043d\u0443\u043b\u044f.<\/em> \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u044b \u0438\u043c\u0435\u0435\u0442\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u044b\u0442 \u0432 \u0432\u0435\u0431-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 React.<\/p>\n<p>  <\/p>\n<p><em>\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/em> \u041c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043d\u0430\u0434 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439 \u043d\u0430 <a href=\"https:\/\/react.dev\/\" rel=\"nofollow noopener noreferrer\">\u0441\u0430\u0439\u0442\u0435 React<\/a>. \u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f, \u0435\u0441\u043b\u0438 \u0432\u0430\u0448 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c \u043a \u0435\u0433\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<p><em>\u0412 \u043f\u0435\u0434\u0430\u0433\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0446\u0435\u043b\u044f\u0445 \u043d\u0430\u0448\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043c\u0435\u043d\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0439, \u0447\u0435\u043c \u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 React.<\/em> \u0412 \u0442\u0435\u043a\u0441\u0442\u0435 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u044b \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438, \u043d\u043e \u043d\u0430\u0448\u0438\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c, \u0430 \u043d\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>  <\/p>\n<h2 id=\"otpravimsya-v-proshloe\">\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u043c\u0441\u044f \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u0435&#8230;<\/h2>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0432\u044b \u043f\u0440\u043e\u0441\u043d\u0443\u043b\u0438\u0441\u044c \u043e\u0434\u043d\u0430\u0436\u0434\u044b \u0443\u0442\u0440\u043e\u043c \u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b\u0438, \u0447\u0442\u043e \u043d\u0430 \u0434\u0432\u043e\u0440\u0435 \u0441\u043d\u043e\u0432\u0430 2003 \u0433\u043e\u0434. \u0412\u0435\u0431-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0437\u0430\u0447\u0430\u0442\u043e\u0447\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0431\u043b\u043e\u0433, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432, \u043b\u0435\u0436\u0430\u0449\u0438\u0445 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u041d\u0430 PHP \u044d\u0442\u043e \u043c\u043e\u0433\u043b\u043e \u0431\u044b \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">&lt;?php   $author = \"Jae Doe\";   $post_content = @file_get_contents(\".\/posts\/hello-world.txt\"); ?> &lt;html>   &lt;head>     &lt;title>My blog&lt;\/title>   &lt;\/head>   &lt;body>     &lt;nav>       &lt;a href=\"\/\">Home&lt;\/a>       &lt;hr>     &lt;\/nav>     &lt;article>       &lt;?php echo htmlspecialchars($post_content); ?>     &lt;\/article>     &lt;footer>       &lt;hr>       &lt;p>&lt;i>(c) &lt;?php echo htmlspecialchars($author); ?>, &lt;?php echo date(\"Y\"); ?>&lt;\/i>&lt;\/p>     &lt;\/footer>   &lt;\/body> &lt;\/html><\/code><\/pre>\n<p>  <\/p>\n<p><em>\u0414\u043b\u044f \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u0438 HTML \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u0438\u0435 \u0442\u0435\u0433\u0438 \u043a\u0430\u043a <code>&lt;nav><\/code>, <code>&lt;article><\/code> \u0438 <code>&lt;footer><\/code> \u0442\u043e\u0433\u0434\u0430 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0438.<\/em><\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c <code>http:\/\/locahost:3000\/hello-world<\/code> \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435, \u044d\u0442\u043e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442 PHP \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 HTML-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441 \u043f\u043e\u0441\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0430 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 <code>.\/posts\/hello-world.txt<\/code>. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u043d\u0430 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u043c Node.js \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { createServer } from 'http'; import { readFile } from 'fs\/promises'; import escapeHtml from  'escape-html';  createServer(async (req, res) => {   const author = \"Jae Doe\";   const postContent = await readFile(\".\/posts\/hello-world.txt\", \"utf8\");   sendHTML(     res,     `&lt;html>       &lt;head>         &lt;title>My blog&lt;\/title>       &lt;\/head>       &lt;body>         &lt;nav>           &lt;a href=\"\/\">Home&lt;\/a>           &lt;hr \/>         &lt;\/nav>         &lt;article>           ${escapeHtml(postContent)}         &lt;\/article>         &lt;footer>           &lt;hr>           &lt;p>&lt;i>(c) ${escapeHtml(author)}, ${new Date().getFullYear()}&lt;\/i>&lt;\/p>         &lt;\/footer>       &lt;\/body>     &lt;\/html>`   ); }).listen(8080);  function sendHTML(res, html) {   res.setHeader(\"Content-Type\", \"text\/html\");   res.end(html); }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/nostalgic-platform-kvog0r?file=%2Fserver.js\" rel=\"nofollow noopener noreferrer\">\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435.<\/a><\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0437\u044f\u0442\u044c \u0441 \u0441\u043e\u0431\u043e\u0439 \u0432 2003 \u0433\u043e\u0434 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0434\u0432\u0438\u0436\u043e\u043a Node.js \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u0415\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u0438\u0432\u043d\u0435\u0441\u0442\u0438 \u0432 \u044d\u0442\u043e\u043c \u043c\u0438\u0440 \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0443 React, \u043a\u0430\u043a\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0432\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u0435? \u0418 \u0432 \u043a\u0430\u043a\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435?<\/p>\n<p>  <\/p>\n<h2 id=\"shag-1-izobretaem-jsx\">\u0428\u0430\u0433 1: \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u0435\u043c JSX<\/h2>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u0431\u0440\u043e\u0441\u0430\u0435\u0442\u0441\u044f \u0432 \u0433\u043b\u0430\u0437\u0430 \u0432 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u0432\u044b\u0448\u0435 \u043a\u043e\u0434\u0435, \u044d\u0442\u043e \u043f\u0440\u044f\u043c\u0430\u044f \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u044f \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438. \u041c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>escapeHtml(postContent)<\/code> \u0432\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u043a\u0430\u043a HTML.<\/p>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043b\u043e\u0433\u0438\u043a\u0438 \u043e\u0442 &#171;\u0448\u0430\u0431\u043b\u043e\u043d\u0430&#187; (template) \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 (template language), \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432, \u043e\u0431\u0435\u0437\u0437\u0430\u0440\u0430\u0436\u0438\u0432\u0430\u0442\u044c (escape) \u0442\u0435\u043a\u0441\u0442 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0434\u043b\u044f \u0434\u043e\u043c\u0435\u043d\u0430 (domain-specific) \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0434\u043b\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0438 \u0446\u0438\u043a\u043b\u043e\u0432. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u043c\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u043c\u0438 \u0432 2000-\u0445 \u0433\u043e\u0434\u0430\u0445.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0432\u0430\u0448\u0438 \u0437\u043d\u0430\u043d\u0438\u044f React \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u0430\u0441 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">createServer(async (req, res) => {   const author = \"Jae Doe\";   const postContent = await readFile(\".\/posts\/hello-world.txt\", \"utf8\");   sendHTML(     res,     &lt;html>       &lt;head>         &lt;title>My blog&lt;\/title>       &lt;\/head>       &lt;body>         &lt;nav>           &lt;a href=\"\/\">Home&lt;\/a>           &lt;hr \/>         &lt;\/nav>         &lt;article>           {postContent}         &lt;\/article>         &lt;footer>           &lt;hr \/>           &lt;p>&lt;i>(c) {author}, {new Date().getFullYear()}&lt;\/i>&lt;\/p>         &lt;\/footer>       &lt;\/body>     &lt;\/html>   ); }).listen(8080);<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u043e\u0445\u043e\u0436\u0435, \u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0448 \u0448\u0430\u0431\u043b\u043e\u043d \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439. \u0412\u043c\u0435\u0441\u0442\u043e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 (string interpolation), \u043c\u044b \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e XML \u0432 JavaScript. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e &#171;\u0438\u0437\u043e\u0431\u0440\u0435\u043b\u0438&#187; JSX (JavaScript and XML). JSX \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0431\u043b\u0438\u0437\u043a\u043e \u043a \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u043b\u043e\u0433\u0438\u043a\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u043d\u043e, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u043a\u0438, \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u0440\u043e\u0434\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0445\/\u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u0442\u0435\u0433\u043e\u0432 HTML \u0438\u043b\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0431\u0435\u0437 \u043e\u0431\u0435\u0437\u0437\u0430\u0440\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c JSX \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u0434\u0435\u0440\u0435\u0432\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f {   $$typeof: Symbol.for(\"react.element\"), \/\/ \u0413\u043e\u0432\u043e\u0440\u0438\u0442 React, \u0447\u0442\u043e \u044d\u0442\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442 JSX (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, &lt;html>)   type: 'html',   props: {     children: [       {         $$typeof: Symbol.for(\"react.element\"),         type: 'head',         props: {           children: {             $$typeof: Symbol.for(\"react.element\"),             type: 'title',             props: { children: 'My blog' }           }         }       },       {         $$typeof: Symbol.for(\"react.element\"),         type: 'body',         props: {           children: [             {               $$typeof: Symbol.for(\"react.element\"),               type: 'nav',               props: {                 children: [{                   $$typeof: Symbol.for(\"react.element\"),                   type: 'a',                   props: { href: '\/', children: 'Home' }                 }, {                   $$typeof: Symbol.for(\"react.element\"),                   type: 'hr',                   props: null                 }]               }             },             {               $$typeof: Symbol.for(\"react.element\"),               type: 'article',               props: {                 children: postContent               }             },             {               $$typeof: Symbol.for(\"react.element\"),               type: 'footer',               props: {                 \/* \u0418 \u0442.\u0434. *\/               }             }           ]         }       }     ]   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0443 HTML, \u0430 \u043d\u0435 \u0434\u0435\u0440\u0435\u0432\u043e JSON (\u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435, \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0438\u0439 \u0434\u0435\u043d\u044c).<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 JSX \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 HTML. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0437\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0443\u0437\u043b\u043e\u0432 (nodes) (\u0441\u0442\u0440\u043e\u043a\u0430, \u0447\u0438\u0441\u043b\u043e, \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u043b\u0438 \u0443\u0437\u0435\u043b JSX \u0441 \u043f\u043e\u0442\u043e\u043c\u043a\u0430\u043c\u0438 (children)) \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u043a\u0443\u0441\u043e\u0447\u043a\u0438 HTML:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function renderJSXToHTML(jsx) {   if (typeof jsx === \"string\" || typeof jsx === \"number\") {     \/\/ \u042d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430. \u041e\u0431\u0435\u0437\u0437\u0430\u0440\u0430\u0436\u0438\u0432\u0430\u0435\u043c \u0435\u0435 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0432 HTML.     return escapeHtml(jsx);   } else if (jsx == null || typeof jsx === \"boolean\") {     \/\/ \u042d\u0442\u043e \u043f\u0443\u0441\u0442\u043e\u0439 \u0443\u0437\u0435\u043b. \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0432 HTML.     return \"\";   } else if (Array.isArray(jsx)) {     \/\/ \u042d\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0443\u0437\u043b\u043e\u0432. \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u0443\u0437\u0435\u043b \u0432 HTML \u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u0432 \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u043a\u0443.     return jsx.map((child) => renderJSXToHTML(child)).join(\"\");   } else if (typeof jsx === \"object\") {     \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c React JSX (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, &lt;div \/>).     if (jsx.$$typeof === Symbol.for(\"react.element\")) {       \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u0432 \u0442\u0435\u0433 HTML.       let html = \"&lt;\" + jsx.type;       for (const propName in jsx.props) {         if (jsx.props.hasOwnProperty(propName) &amp;&amp; propName !== \"children\") {           html += \" \";           html += propName;           html += \"=\";           html += escapeHtml(jsx.props[propName]);         }       }       html += \">\";       html += renderJSXToHTML(jsx.props.children);       html += \"&lt;\/\" + jsx.type + \">\";       return html;       \/\/ \u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442.     } else throw new Error(\"Cannot render an object.\");     \/\/ \u041d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e.   } else throw new Error(\"Not implemented.\"); }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/recursing-kepler-yw7dlx?file=%2Fserver.js\" rel=\"nofollow noopener noreferrer\">\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435.<\/a> \u041f\u0440\u0438\u043c. \u043f\u0435\u0440.: \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>start<\/code> \u0432 <code>package.json<\/code> (<code>nodemon -- --experimental-loader .\/node-jsx-loader.js .\/server.js<\/code>). \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043a\u043e\u0434 \u0444\u0430\u0439\u043b\u0430 <code>server.js<\/code> \u0442\u0440\u0430\u043d\u0441\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Babel (<code>@babel\/plugin-transform-react-jsx<\/code>) \u2014 \u043f\u0435\u0440\u0435\u0434 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>renderJSXToHTML<\/code> JSX \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442. \u0423\u0432\u0438\u0434\u0435\u0442\u044c \u044d\u0442\u043e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u043c\u043e\u0436\u043d\u043e, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 <code>console.log(jsx)<\/code> \u0432 \u043d\u0430\u0447\u0430\u043b\u043e <code>renderJSXToHTML()<\/code> \u0438 \u043d\u0430\u0436\u0430\u0432 <code>Open logs<\/code> \u0432 \u0432\u044b\u043f\u0430\u0434\u0430\u044e\u0449\u0435\u043c \u043c\u0435\u043d\u044e \u043e\u043a\u043d\u0430 \u043f\u0440\u0435\u0432\u044c\u044e.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 JSX \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 HTML \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u043a\u0430\u043a &#171;\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430&#187; (SSR \u2014 Server-Side Rendering). <em>\u0412\u0430\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e RSC \u0438 SSR \u2014 \u0434\u0432\u0435 \u043e\u0447\u0435\u043d\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u0432\u0435\u0449\u0438 (\u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435).<\/em> \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u0441 SSR, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e \u043f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0449\u044c, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u0435. \u041d\u043e \u044d\u0442\u043e \u043b\u0438\u0448\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u0448\u0430\u0433, \u0438 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438.<\/p>\n<p>  <\/p>\n<h2 id=\"shag-2-izobretaem-komponenty\">\u0428\u0430\u0433 2: \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b<\/h2>\n<p>  <\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 &#171;\u0436\u0435\u043b\u0430\u043d\u043d\u043e\u0439&#187; \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e, \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u041d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0442\u043e\u0433\u043e, \u0433\u0434\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u0434, \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0438\u043b\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0435, \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0447\u0430\u0441\u0442\u0438 UI (User Interface \u2014 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441) \u043d\u0430 \u043a\u0443\u0441\u043e\u0447\u043a\u0438, \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u0438\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u043e\u043f\u043e\u0432 (props, properties \u2014 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430).<\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0437\u0434\u0435\u043b\u0438\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430 \u0434\u0432\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>BlogPostPage<\/code> \u0438 <code>Footer<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function BlogPostPage({ postContent, author }) {   return (     &lt;html>       &lt;head>         &lt;title>My blog&lt;\/title>       &lt;\/head>       &lt;body>         &lt;nav>           &lt;a href=\"\/\">Home&lt;\/a>           &lt;hr \/>         &lt;\/nav>         &lt;article>           {postContent}         &lt;\/article>         &lt;Footer author={author} \/>       &lt;\/body>     &lt;\/html>   ); }  function Footer({ author }) {   return (     &lt;footer>       &lt;hr \/>       &lt;p>         &lt;i>           (c) {author} {new Date().getFullYear()}         &lt;\/i>       &lt;\/p>     &lt;\/footer>   ); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435, \u0437\u0430\u043c\u0435\u043d\u0438\u043c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e JSX \u043d\u0430 <code>&lt;BlogPostPage postContent={postContent} author={author} \/><\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">createServer(async (req, res) => {   const author = \"Jae Doe\";   const postContent = await readFile(\".\/posts\/hello-world.txt\", \"utf8\");   sendHTML(     res,     &lt;BlogPostPage       postContent={postContent}       author={author}     \/>   ); }).listen(8080);<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0431\u0435\u0437 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f <code>renderJSXToHTML()<\/code>, \u0442\u043e \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 HTML \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u043e\u043c\u0430\u043d\u043d\u044b\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"html\">&lt;!-- \u042d\u0442\u043e \u043d\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u0430\u043a \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 HTML... --> &lt;function BlogPostPage({postContent,author}) {...}> &lt;\/function BlogPostPage({postContent,author}) {...}><\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>renderJSXToHTML<\/code> (\u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 JSX \u0432 HTML) &#171;\u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442&#187;, \u0447\u0442\u043e <code>jsx.type<\/code> \u2014 \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u0442\u0440\u043e\u043a\u0430 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0442\u0435\u0433\u0430 HTML (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>\"html\"<\/code>, <code>\"footer\"<\/code> \u0438\u043b\u0438 <code>\"p\"<\/code>):<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">if (jsx.$$typeof === Symbol.for(\"react.element\")) {   \/\/ \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0442\u0435\u0433\u0438 HTML (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, &lt;p>).   let html = \"&lt;\" + jsx.type;   \/\/ ...   html += \"&lt;\/\" + jsx.type + \">\";   return html; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e <code>BlogPostPage<\/code> \u2014 \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 <code>\"&lt;\" + jsx.type + \">\"<\/code> &#171;\u043f\u0435\u0447\u0430\u0442\u0430\u0435\u0442&#187; \u0435\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434. \u041c\u044b \u043d\u0435 \u0445\u043e\u0442\u0438\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438 \u0442\u0435\u0433\u0430 HTML. \u0412\u044b\u0437\u043e\u0432\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u043c (serialize) \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0435\u044e JSX \u0432 HTML:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">if (jsx.$$typeof === Symbol.for(\"react.element\")) {   if (typeof jsx.type === \"string\") { \/\/ \u042d\u0442\u043e \u0442\u0435\u0433 (\u0442\u0430\u043a\u043e\u0439 \u043a\u0430\u043a &lt;div>)?     \/\/ \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0442\u0435\u0433\u0438 HTML (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, &lt;p>).     let html = \"&lt;\" + jsx.type;     \/\/ ...     html += \"&lt;\/\" + jsx.type + \">\";     return html;   } else if (typeof jsx.type === \"function\") { \/\/ \u042d\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 (\u0442\u0430\u043a\u043e\u0439 \u043a\u0430\u043a &lt;BlogPostPage>)?     \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441 \u043f\u0440\u043e\u043f\u0430\u043c\u0438 \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0438\u043c JSX \u0432 HTML.     const Component = jsx.type;     const props = jsx.props;     const returnedJsx = Component(props);     return renderJSXToHTML(returnedJsx);     \/\/ \u041d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e.   } else throw new Error(\"Not implemented.\"); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 HTML \u044d\u043b\u0435\u043c\u0435\u043d\u0442 JSX, \u0442\u0430\u043a\u043e\u0439 \u043a\u0430\u043a <code>&lt;BlogPostPage author=\"Jae Doe\" \/><\/code>, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f <code>{ author: \"Jae Doe\" }<\/code>. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 JSX, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043d\u043e\u0432\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 <code>renderJSXToHTML()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u043f\u043e\u0432.<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/thirsty-frost-8oug3o?file=%2Fserver.js\" rel=\"nofollow noopener noreferrer\">\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435.<\/a><\/p>\n<p>  <\/p>\n<h2 id=\"shag-3-dobavlyaem-routing\">\u0428\u0430\u0433 3: \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u043e\u0443\u0442\u0438\u043d\u0433<\/h2>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0432 \u0431\u043b\u043e\u0433.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u043f\u043e \u0442\u0430\u043a\u043e\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443, \u043a\u0430\u043a <code>\/hello-world<\/code>, \u0434\u043e\u043b\u0436\u043d\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u0441 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c \u0444\u0430\u0439\u043b\u0430 <code>.\/posts\/hello-world.txt<\/code>, \u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e URL (Uniform Resource Locator \u2014 \u0435\u0434\u0438\u043d\u044b\u0439 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432) \u2014 \u0434\u043b\u0438\u043d\u043d\u0430\u044f \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c \u0432\u0441\u0435\u0445 \u043f\u043e\u0441\u0442\u043e\u0432. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 <code>BlogIndexPage<\/code>, \u0438\u043c\u0435\u044e\u0449\u0443\u044e \u043e\u0431\u0449\u0438\u0439 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439 <code>BlogPostPage<\/code> \u043c\u0430\u043a\u0435\u0442 (shared layout), \u043d\u043e \u0434\u0440\u0443\u0433\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0432\u043d\u0443\u0442\u0440\u0438.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>BlogPostPage<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0446\u0435\u043b\u0438\u043a\u043e\u043c, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e <code>&lt;html><\/code>. \u0418\u0437\u0432\u043b\u0435\u0447\u0435\u043c \u043e\u0431\u0449\u0438\u0435 \u0434\u043b\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0447\u0430\u0441\u0442\u0438 UI (<code>header<\/code> \u0438 <code>footer<\/code>) \u0438\u0437 <code>BlogPostPage<\/code> \u0432 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 (reusable) \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>BlogLayout<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function BlogLayout({ children }) {   const author = \"Jae Doe\";   return (     &lt;html>       &lt;head>         &lt;title>My blog&lt;\/title>       &lt;\/head>       &lt;body>         &lt;nav>           &lt;a href=\"\/\">Home&lt;\/a>           &lt;hr \/>         &lt;\/nav>         &lt;main>           {children}         &lt;\/main>         &lt;Footer author={author} \/>       &lt;\/body>     &lt;\/html>   ); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c <code>BlogPostPage<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c (slot) \u0432\u043d\u0443\u0442\u0440\u044c \u043c\u0430\u043a\u0435\u0442\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function BlogPostPage({ postSlug, postContent }) {   return (     &lt;section>       &lt;h2>         &lt;a href={\"\/\" + postSlug}>{postSlug}&lt;\/a>       &lt;\/h2>       &lt;article>{postContent}&lt;\/article>     &lt;\/section>   ); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c <code>&lt;BlogPostPage><\/code>, \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u0432 <code>&lt;BlogLayout><\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/fj\/nl\/we\/fjnlweicggthulvonh-wx7gtfgi.png\" data-src=\"https:\/\/habrastorage.org\/webt\/fj\/nl\/we\/fjnlweicggthulvonh-wx7gtfgi.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>BlogIndexPage<\/code>, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u043e\u0441\u0442 \u0432 <code>.\/posts\/*.txt<\/code> \u043e\u0434\u0438\u043d \u0437\u0430 \u0434\u0440\u0443\u0433\u0438\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function BlogIndexPage({ postSlugs, postContents }) {   return (     &lt;section>       &lt;h1>Welcome to my blog&lt;\/h1>       &lt;div>         {postSlugs.map((postSlug, index) => (           &lt;section key={postSlug}>             &lt;h2>               &lt;a href={\"\/\" + postSlug}>{postSlug}&lt;\/a>             &lt;\/h2>             &lt;article>{postContents[index]}&lt;\/article>           &lt;\/section>         ))}       &lt;\/div>     &lt;\/section>   ); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044c \u0435\u0433\u043e \u0432 <code>BlogLayout<\/code>, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0438\u043c\u0435\u043b \u0442\u0430\u043a\u0443\u044e \u0436\u0435 \u0448\u0430\u043f\u043a\u0443 \u0438 \u043f\u043e\u0434\u0432\u0430\u043b:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/_9\/wg\/c8\/_9wgc8tchp2dz3jv_f7v4dytvsy.png\" data-src=\"https:\/\/habrastorage.org\/webt\/_9\/wg\/c8\/_9wgc8tchp2dz3jv_f7v4dytvsy.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 (server handler) \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u043b \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 URL, \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u043b \u0434\u043b\u044f \u043d\u0435\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043b \u0435\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u0430\u043a\u0435\u0442\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">createServer(async (req, res) => {   try {     const url = new URL(req.url, `http:\/\/${req.headers.host}`);     \/\/ \u0418\u0449\u0435\u043c \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 URL \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439 \u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.     const page = await matchRoute(url);     \/\/ \u041e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u043e\u0432\u043f\u0430\u0432\u0448\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0432 \u043e\u0431\u0449\u0438\u0439 \u043c\u0430\u043a\u0435\u0442.     sendHTML(res, &lt;BlogLayout>{page}&lt;\/BlogLayout>);   } catch (err) {     console.error(err);     res.statusCode = err.statusCode ?? 500;     res.end();   } }).listen(8080);  async function matchRoute(url) {   if (url.pathname === \"\/\") {     \/\/ \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0432\u0441\u0435\u0445 \u043f\u043e\u0441\u0442\u043e\u0432.     \/\/ \u0427\u0438\u0442\u0430\u0435\u043c \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043f\u043e\u0441\u0442\u043e\u0432 \u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0438\u0445 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435.     const postFiles = await readdir(\".\/posts\");     const postSlugs = postFiles.map((file) => file.slice(0, file.lastIndexOf(\".\")));     const postContents = await Promise.all(       postSlugs.map((postSlug) =>         readFile(\".\/posts\/\" + postSlug + \".txt\", \"utf8\")       )     );     return &lt;BlogIndexPage postSlugs={postSlugs} postContents={postContents} \/>;   } else {     \/\/ \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430.     \/\/ \u0427\u0438\u0442\u0430\u0435\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0444\u0430\u0439\u043b \u0438\u0437 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043f\u043e\u0441\u0442\u043e\u0432.     const postSlug = sanitizeFilename(url.pathname.slice(1));     try {       const postContent = await readFile(\".\/posts\/\" + postSlug + \".txt\", \"utf8\");       return &lt;BlogPostPage postSlug={postSlug} postContent={postContent} \/>;     } catch (err) {       throwNotFound(err);     }   } }  function throwNotFound(cause) {   \/\/ \u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e.   const notFound = new Error(\"Not found.\", { cause });   notFound.statusCode = 404;   throw notFound; }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/trusting-turing-bi5vjr?file=%2Fserver.js\" rel=\"nofollow noopener noreferrer\">\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435.<\/a><\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f (navigate) \u043f\u043e \u0431\u043b\u043e\u0433\u0443. \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u043a\u043e\u0434 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0441\u043b\u0435\u0433\u043a\u0430 \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u043d\u044b\u043c \u0438 \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u0438\u043c. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c \u044d\u0442\u043e \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435.<\/p>\n<p>  <\/p>\n<h2 id=\"shag-4-izobretaem-asinhronnye-komponenty\">\u0428\u0430\u0433 4: \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u0435\u043c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b<\/h2>\n<p>  <\/p>\n<p>\u0412\u044b \u043c\u043e\u0433\u043b\u0438 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u0430 \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 <code>BlogIndexPage<\/code> \u0438 <code>BlogPostPage<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u043e\u0447\u0442\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/hx\/kg\/eh\/hxkgehok87ehkrow4nbpkyzxk5i.png\" data-src=\"https:\/\/habrastorage.org\/webt\/hx\/kg\/eh\/hxkgehok87ehkrow4nbpkyzxk5i.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/ln\/bv\/th\/lnbvthbco2aaui0l1mrs4cuayvs.png\" data-src=\"https:\/\/habrastorage.org\/webt\/ln\/bv\/th\/lnbvthbco2aaui0l1mrs4cuayvs.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0411\u044b\u043b\u043e \u0431\u044b \u0437\u0434\u043e\u0440\u043e\u0432\u043e \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u044d\u0442\u043e \u0432 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442. \u041e\u0434\u043d\u0430\u043a\u043e, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>Post<\/code>, \u043d\u0430\u043c \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u043d\u0430\u0434\u043e \u0431\u0443\u0434\u0435\u0442 \u043a\u0430\u043a-\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c <code>content<\/code> \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function Post({ slug, content }) { \/\/ \u041a\u0442\u043e-\u0442\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u043f `content` \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 :-(   return (     &lt;section>       &lt;h2>         &lt;a href={\"\/\" + slug}>{slug}&lt;\/a>       &lt;\/h2>       &lt;article>{content}&lt;\/article>     &lt;\/section>   ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043b\u043e\u0433\u0438\u043a\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 <code>content<\/code> \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u043e\u0432 \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/codesandbox.io\/p\/sandbox\/trusting-turing-bi5vjr?file=%2Fserver.js%3A24%2C1-28%2C7\" rel=\"nofollow noopener noreferrer\">\u0437\u0434\u0435\u0441\u044c<\/a> \u0438 <a href=\"https:\/\/codesandbox.io\/p\/sandbox\/trusting-turing-bi5vjr?file=%2Fserver.js%3A33%2C1-36%2C9\" rel=\"nofollow noopener noreferrer\">\u0437\u0434\u0435\u0441\u044c<\/a>. \u041c\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0435\u0433\u043e \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 API (Application Programming Interface \u2014 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u0440\u0438\u043a\u043b\u0430\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f) <code>readFile<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c, \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043f\u0440\u044f\u043c\u043e \u0432 \u0434\u0435\u0440\u0435\u0432\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 (\u0442\u043e\u0442 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u043c\u043e\u0434\u0443\u043b\u044c <code>fs<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043d\u0435 \u0440\u0435\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432\u043c\u0435\u0441\u0442\u043e \u0447\u0442\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u043b\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u044e\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443).<\/p>\n<p>  <\/p>\n<p>\u0418\u043b\u0438 \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u043c\u043e\u0436\u0435\u043c?<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u0440\u0438\u0432\u044b\u043a\u043b\u0438 \u043a React \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u044b \u043f\u0440\u0438\u0432\u044b\u043a\u043b\u0438 \u043a \u0438\u0434\u0435\u0435 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e API \u0432\u0440\u043e\u0434\u0435 <code>fs.readFile<\/code> \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u0445. \u0414\u0430\u0436\u0435 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 React SSR \u0438\u043d\u0442\u0443\u0438\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0432\u0430\u043c, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 API, \u0432\u0440\u043e\u0434\u0435 <code>fs.readFile<\/code>, \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0443\u0442.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u0435\u0441\u043b\u0438 \u0431\u044b \u0432\u044b \u043f\u043e\u043f\u044b\u0442\u0430\u043b\u0438\u0441\u044c \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c \u044d\u0442\u043e \u043a\u043e\u043c\u0443-\u0442\u043e \u0432 2003 \u0433\u043e\u0434\u0443, \u043e\u043d\u0438 \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u043b\u0438 \u0431\u044b \u044d\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u043c.<\/p>\n<p>  <\/p>\n<p>\u0411\u0443\u0434\u0435\u043c \u0440\u0435\u0448\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043f\u043e \u043c\u0435\u0440\u0435 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f. \u041f\u043e\u043a\u0430 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u0440\u0432\u0435\u0440, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043a\u043e\u0434\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435. \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432\u043f\u043e\u043b\u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0435\u0440\u0432\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u043e\u0436\u0434\u0430\u0442\u044c \u0441 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0435\u0439 HTML \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0435\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b, \u0438 \u043e\u043d \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432 \u043a \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044e.<\/p>\n<p>  <\/p>\n<p>\u0423\u0434\u0430\u043b\u0438\u043c \u043f\u0440\u043e\u043f <code>content<\/code> \u0438 \u0441\u0434\u0435\u043b\u0430\u0435\u043c <code>Post<\/code> \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0449\u0435\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u044b\u0437\u043e\u0432\u0430 <code>await readFile()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function Post({ slug }) {   let content;   try {     content = await readFile(\".\/posts\/\" + slug + \".txt\", \"utf8\");   } catch (err) {     throwNotFound(err);   }   return (     &lt;section>       &lt;h2>         &lt;a href={\"\/\" + slug}>{slug}&lt;\/a>       &lt;\/h2>       &lt;article>{content}&lt;\/article>     &lt;\/section>   ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0435\u043c <code>BlogIndexPage<\/code> \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0435\u0439 \u0437\u0430 \u043f\u0435\u0440\u0435\u0431\u043e\u0440 \u043f\u043e\u0441\u0442\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>await readdir()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function BlogIndexPage() {   const postFiles = await readdir(\".\/posts\");   const postSlugs = postFiles.map((file) =>     file.slice(0, file.lastIndexOf(\".\"))   );   return (     &lt;section>       &lt;h1>Welcome to my blog&lt;\/h1>       &lt;div>         {postSlugs.map((slug) => (           &lt;Post key={slug} slug={slug} \/>         ))}       &lt;\/div>     &lt;\/section>   ); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>Post<\/code> \u0438 <code>BlogIndexPage<\/code> \u0441\u0430\u043c\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0441\u0435\u0431\u044f, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c <code>matchRoute()<\/code> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c <code>&lt;Router><\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function Router({ url }) {   let page;   if (url.pathname === \"\/\") {     page = &lt;BlogIndexPage \/>;   } else {     const postSlug = sanitizeFilename(url.pathname.slice(1));     page = &lt;BlogPostPage postSlug={postSlug} \/>;   }   return &lt;BlogLayout>{page}&lt;\/BlogLayout>; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0432\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 <code>&lt;Router><\/code><\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">createServer(async (req, res) => {   try {     const url = new URL(req.url, `http:\/\/${req.headers.host}`);     await sendHTML(res, &lt;Router url={url} \/>);   } catch (err) {     console.error(err);     res.statusCode = err.statusCode ?? 500;     res.end();   } }).listen(8080);<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0433\u043e\u0434\u0438\u0442\u0435, \u043d\u0430\u043c \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u041a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c?<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0439\u0434\u0435\u043c \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>renderJSXToHTML()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">} else if (typeof jsx.type === \"function\") {   const Component = jsx.type;   const props = jsx.props;   const returnedJsx = Component(props); \/\/ &lt;--- \u0412\u043e\u0442 \u0433\u0434\u0435 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b   return renderJSXToHTML(returnedJsx); } else throw new Error(\"Not implemented.\");<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c\u0438, \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0434\u0435\u0441\u044c \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e <code>await<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ ... const returnedJsx = await Component(props); \/\/ ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0441\u0430\u043c\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>renderJSXToHTML<\/code> \u0442\u0435\u043f\u0435\u0440\u044c \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function renderJSXToHTML(jsx)  {   \/\/ ... }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043b\u044e\u0431\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432 \u0434\u0435\u0440\u0435\u0432\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c, \u0430 \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 HTML &#171;\u0436\u0434\u0435\u0442&#187; \u0438\u0445 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f (\u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0432\u0432\u0438\u0434\u0443 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u043c\u0438\u0441\u0430).<\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0432 \u043d\u043e\u0432\u043e\u043c \u043a\u043e\u0434\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u043e &#171;\u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0435&#187; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0432\u0441\u0435\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f <code>BlogIndexPage<\/code> \u0432 \u0446\u0438\u043a\u043b\u0435. \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>BlogIndexPage<\/code> \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 <code>Post<\/code>, \u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u0430\u0436\u0434\u044b\u0439 <code>Post<\/code> \u0437\u043d\u0430\u0435\u0442, \u043a\u0430\u043a \u0447\u0438\u0442\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0444\u0430\u0439\u043b\u0430.<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/relaxed-pare-gicsdi?file=%2Fserver.js\" rel=\"nofollow noopener noreferrer\">\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435.<\/a><\/p>\n<p>  <\/p>\n<blockquote><p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u044d\u0442\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u0439, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u0430\u0436\u0434\u044b\u0439 <code>await<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u043c&#187;. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0434\u0430\u0436\u0435 <em>\u043d\u0430\u0447\u0430\u0442\u044c<\/em> \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 HTML \u0434\u043e \u0435\u0433\u043e <em>\u043f\u043e\u043b\u043d\u043e\u0439<\/em> \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438. \u0412 \u0438\u0434\u0435\u0430\u043b\u0435, \u043d\u0430\u043c \u0431\u044b \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c HTML \u043f\u043e \u043c\u0435\u0440\u0435 \u0435\u0433\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 (\u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 \u043f\u043e\u0442\u043e\u043a\u0435 (stream)). \u041c\u044b \u0441\u0444\u043e\u043a\u0443\u0441\u0438\u0440\u0443\u0435\u043c\u0441\u044f \u043d\u0430 \u043f\u043e\u0442\u043e\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043e\u0441\u0442\u0430\u0432\u0438\u043c \u044d\u0442\u043e \u0431\u0435\u0437 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f. \u041e\u0434\u043d\u0430\u043a\u043e, \u0432\u0430\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u0443\u044e \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0437\u0436\u0435 \u0431\u0435\u0437 \u043a\u0430\u043a\u0438\u0445-\u043b\u0438\u0431\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0441\u0430\u043c\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u041a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <code>await<\/code> \u0434\u043b\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0447\u0442\u043e \u043d\u0435\u0438\u0437\u0431\u0435\u0436\u043d\u043e), \u043d\u043e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b <code>await<\/code> \u043f\u043e\u0442\u043e\u043c\u043a\u043e\u0432, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f <code>async<\/code>. \u0412\u043e\u0442 \u043f\u043e\u0447\u0435\u043c\u0443 React \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0434\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432.<\/p><\/blockquote>\n<p>  <\/p>\n<h2 id=\"shag-5-sohranyaem-sostoyanie-pri-navigacii\">\u0428\u0430\u0433 5: \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438<\/h2>\n<p>  <\/p>\n<p>\u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0435\u0440 \u0443\u043c\u0435\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0440\u043e\u0443\u0442 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 HTML:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function sendHTML(res, jsx) {   const html = await renderJSXToHTML(jsx);   res.setHeader(\"Content-Type\", \"text\/html\");   res.end(html); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u2014 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d \u0434\u043b\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f HTML \u2014 \u043d\u043e \u043d\u0435 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0439. \u041c\u044b \u0431\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c &#171;\u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0432\u0448\u0438\u0435\u0441\u044f \u0447\u0430\u0441\u0442\u0438&#187; \u043d\u0430 \u043c\u0435\u0441\u0442\u0435 (in-place), \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043a\u0430\u043a \u0432\u043d\u0443\u0442\u0440\u0438, \u0442\u0430\u043a \u0438 \u0432\u043e\u043a\u0440\u0443\u0433 \u044d\u0442\u0438\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438\u043d\u043f\u0443\u0442\u0430, \u0432\u0438\u0434\u0435\u043e, \u043f\u043e\u043f\u0430\u043f\u0430 \u0438 \u0442.\u0434.). \u042d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u043c\u0443\u0442\u0430\u0446\u0438\u0438 (\u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f \u043a \u043f\u043e\u0441\u0442\u0443) \u0431\u043e\u043b\u0435\u0435 \u043f\u043b\u0430\u0432\u043d\u044b\u043c\u0438.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b <a href=\"https:\/\/codesandbox.io\/p\/sandbox\/heuristic-lalande-gp6gcj?file=%2Fserver.js%3A77%2C11-77%2C20\" rel=\"nofollow noopener noreferrer\"><code>\u0434\u043e\u0431\u0430\u0432\u0438\u043c &lt;input \/><\/code><\/a> \u0432 <code>&lt;nav><\/code> \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 <code>BlogLayout<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"html\">&lt;nav>   &lt;a href=\"\/\">Home&lt;\/a>   &lt;hr \/>   &lt;input \/>   &lt;hr \/> &lt;\/nav><\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e, \u043a\u0430\u043a \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438\u043d\u043f\u0443\u0442\u0430 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043f\u043e \u0431\u043b\u043e\u0433\u0443:<\/p>\n<p>  <\/p>\n<div class=\"oembed\">\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/64895af0575700484e6d4766\" data-style=\"\" id=\"64895af0575700484e6d4766\" width=\"\"><\/div>\n<\/div>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u043c \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0431\u043b\u043e\u0433\u0430, \u043d\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0435\u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u044b\u043c. \u041c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u043b\u0441\u044f \u043f\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c \u0431\u0435\u0437 \u043f\u043e\u0442\u0435\u0440\u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0418\u0441\u043f\u0440\u0430\u0432\u0438\u043c \u044d\u0442\u043e \u0432 \u0442\u0440\u0438 \u044d\u0442\u0430\u043f\u0430:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 JS \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0430 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0439 (\u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0431\u0435\u0437 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b).<\/li>\n<li>\u041d\u0430\u0443\u0447\u0438\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043e \u0441\u0435\u0442\u0438 JSX \u0432\u043c\u0435\u0441\u0442\u043e HTML \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0439.<\/li>\n<li>\u041d\u0430\u0443\u0447\u0438\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f JSX \u0431\u0435\u0437 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f DOM (Document Object Model \u2014 \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430) (\u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c React).<\/li>\n<\/ol>\n<p>  <\/p>\n<h3 id=\"shag-51-perehvatyvaem-navigacii\">\u0428\u0430\u0433 5.1: \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438<\/h3>\n<p>  <\/p>\n<p>\u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0442\u0435\u0433 <code>&lt;script><\/code> \u0432 \u043d\u043e\u0432\u043e\u043c \u0444\u0430\u0439\u043b\u0435 <code>client.js<\/code>. \u0412 \u044d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043c\u044b \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0448\u0435\u043c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043f\u043e \u0441\u0430\u0439\u0442\u0443 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e \u043a\u043b\u0438\u043a \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>navigate<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function navigate(pathname) {   \/\/ TODO }  window.addEventListener(\"click\", (e) => {   \/\/ \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0438\u043a\u0438 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435.   if (e.target.tagName !== \"A\") {     return;   }   \/\/ \u0418\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u043c \"\u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0432 \u043d\u043e\u0432\u043e\u043c \u043e\u043a\u043d\u0435\".   if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {     return;   }   \/\/ \u0418\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u043c \u0432\u043d\u0435\u0448\u043d\u0438\u0435 URL.   const href = e.target.getAttribute(\"href\");   if (!href.startsWith(\"\/\")) {     return;   }   \/\/ \u041e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u043c, \u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c URL.   e.preventDefault();   window.history.pushState(null, null, href);   \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443.   navigate(href); }, true);  window.addEventListener(\"popstate\", () => {   \/\/ \u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \"\u0412\u043f\u0435\u0440\u0435\u0434\/\u041d\u0430\u0437\u0430\u0434\" \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443.   navigate(window.location.pathname); });<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>navigate<\/code> \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0432\u0435\u0442 HTML \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0440\u043e\u0443\u0442\u0430 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f DOM:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">let currentPathname = window.location.pathname;  async function navigate(pathname) {   currentPathname = pathname;   \/\/ \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c HTML \u0434\u043b\u044f \u0440\u043e\u0443\u0442\u0430, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434.   const response = await fetch(pathname);   const html = await response.text();    if (pathname === currentPathname) {     \/\/ \u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0447\u0430\u0441\u0442\u044c HTML, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0443\u044e\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0442\u0435\u0433\u0430 &lt;body>.     const bodyStartIndex = html.indexOf(\"&lt;body>\") + \"&lt;body>\".length;     const bodyEndIndex = html.lastIndexOf(\"&lt;\/body>\");     const bodyHTML = html.slice(bodyStartIndex, bodyEndIndex);      \/\/ \u0417\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.     document.body.innerHTML = bodyHTML;   } }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/agitated-bush-ql7kid?file=%2Fclient.js\" rel=\"nofollow noopener noreferrer\">\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435.<\/a><\/p>\n<p>  <\/p>\n<h3 id=\"shag-52-otpravlyaem-jsx-po-seti\">\u0428\u0430\u0433 5.2: \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c JSX \u043f\u043e \u0441\u0435\u0442\u0438<\/h3>\n<p>  <\/p>\n<p>\u041f\u043e\u043c\u043d\u0438\u0442\u0435 \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u0435\u0440\u0435\u0432\u0430 JSX?<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">{   $$typeof: Symbol.for(\"react.element\"),   type: 'html',   props: {     children: [       {         $$typeof: Symbol.for(\"react.element\"),         type: 'head',         props: {           \/\/ \u0418 \u0442.\u0434.<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u043e\u0432\u044b\u0439 \u0440\u0435\u0436\u0438\u043c. \u041a\u043e\u0433\u0434\u0430 URL \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043e\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 <code>?jsx<\/code>, \u0432 \u043e\u0442\u0432\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u0435\u0440\u0435\u0432\u043e, \u0430 \u043d\u0435 HTML. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u043b\u0435\u0433\u043a\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0447\u0430\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c, \u0438 \u0442\u043e\u0447\u0435\u0447\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c DOM. \u042d\u0442\u043e \u0440\u0435\u0448\u0438\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f <code>&lt;input><\/code>, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043f\u0440\u0438\u0447\u0438\u043d\u0430, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0442\u0430\u043a \u0434\u0435\u043b\u0430\u0435\u043c. \u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 (\u043d\u0435 \u0432 \u044d\u0442\u043e\u0439!) \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435, \u043a\u0430\u043a \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e (\u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e HTML) \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0443.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u0437\u043c\u0435\u043d\u0438\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u043d\u043e\u0432\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>sendJSX<\/code> \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 (search param) <code>?jsx<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">createServer(async (req, res) => {   try {     const url = new URL(req.url, `http:\/\/${req.headers.host}`);     if (url.pathname === \"\/client.js\") {       \/\/ ...     } else if (url.searchParams.has(\"jsx\")) {       url.searchParams.delete(\"jsx\"); \/\/ \u041e\u0447\u0438\u0449\u0430\u0435\u043c URL, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 &lt;Router>       await sendJSX(res, &lt;Router url={url} \/>);     } else {       await sendHTML(res, &lt;Router url={url} \/>);     }     \/\/ ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 <code>sendJSX()<\/code> \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u0435\u0440\u0435\u0432\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 JSON \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>JSON.stringify(jsx)<\/code> \u0434\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u043e \u0441\u0435\u0442\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function sendJSX(res, jsx) {   const jsxString = JSON.stringify(jsx, null, 2);   res.setHeader(\"Content-Type\", \"application\/json\");   res.end(jsxString); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c &#171;\u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 JSX&#187;, \u043d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043f\u043e \u0441\u0435\u0442\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435 JSX (\u0442\u0430\u043a\u043e\u0439 \u043a\u0430\u043a <code>\"&lt;Foo \/>\"<\/code>). \u041c\u044b \u0431\u0435\u0440\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u0435\u0440\u0435\u0432\u0430, \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 JSX, \u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0435\u0433\u043e \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 JSON. \u041e\u0434\u043d\u0430\u043a\u043e \u0444\u043e\u0440\u043c\u0430\u0442 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u043f\u043e\u0437\u0436\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f (\u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 RSC \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u043e\u0439 \u0444\u043e\u0440\u043c\u0430\u0442, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u044d\u0442\u043e\u0439 \u0441\u0435\u0440\u0438\u0438).<\/p>\n<p>  <\/p>\n<p>\u0412\u0437\u0433\u043b\u044f\u043d\u0435\u043c \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u0441\u0435\u0442\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function navigate(pathname) {   currentPathname = pathname;   const response = await fetch(pathname + \"?jsx\");   const jsonString = await response.text();   if (pathname === currentPathname) {     alert(jsonString);   } }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/heuristic-bartik-gk8ggy?file=%2Fserver.js%3A1%2C1\" rel=\"nofollow noopener noreferrer\">\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435.<\/a> \u0415\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0435 \u0433\u043b\u0430\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 (<code>\/<\/code>) \u0438 \u043d\u0430\u0436\u043c\u0435\u0442\u0435 \u043d\u0430 \u0441\u0441\u044b\u043b\u043a\u0443, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0441 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">{   \"key\": null,   \"ref\": null,   \"props\": {     \"url\": \"http:\/\/localhost:3000\/hello-world\"   },   \/\/ ... }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043e JSX \u0432\u0440\u043e\u0434\u0435 <code>&lt;html>...&lt;\/html><\/code>, \u043d\u043e \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0448 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 JSX \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">&lt;Router url=\"http:\/\/localhost:3000\/hello-world\" \/> \/\/ { \/\/   $$typeof: Symbol.for('react.element'), \/\/   type: Router, \/\/   props: { url: \"http:\/\/localhost:3000\/hello-world\" } }, \/\/    ... \/\/ }<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u041f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u044d\u0442\u043e\u0442 JSX \u0432 JSON \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 &#171;\u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0440\u0430\u043d\u043e&#187;, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u043c, \u043a\u0430\u043a\u043e\u0439 JSX <code>Router<\/code> \u0445\u043e\u0447\u0435\u0442 \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c, \u0430 <code>Router<\/code> \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u041d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>Router<\/code> \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c \u043a\u0430\u043a\u043e\u0439 JSX \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0443.<\/em><\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0432\u044b\u0437\u043e\u0432\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>Router<\/code> \u0441 <code>{ url: \"http:\/\/localhost:3000\/hello-world\" }<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u043e\u043f\u0430, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0442\u0430\u043a\u043e\u0439 \u043a\u0443\u0441\u043e\u043a JSX:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">&lt;BlogLayout>   &lt;BlogIndexPage \/> &lt;\/BlogLayout><\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u044f\u0442\u044c &#171;\u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0440\u0430\u043d\u043e&#187; \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 JSX \u0432 JSON \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u0445\u043e\u0447\u0435\u0442 \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c <code>BlogLayout<\/code> \u2014 \u0438 \u043e\u043d \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u041d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>BlogLayout<\/code> \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c, \u043a\u0430\u043a\u043e\u0439 JSX \u043e\u043d \u0445\u043e\u0447\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0438 \u0442.\u0434.<\/p>\n<p>  <\/p>\n<p><em>\u041e\u043f\u044b\u0442\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 React \u043c\u043e\u0433\u0443\u0442 \u0437\u0430\u0434\u0430\u0442\u044c\u0441\u044f \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c: \u043c\u043e\u0436\u0435\u043c \u043b\u0438 \u043c\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f? \u0418\u0449\u0438\u0442\u0435 \u043e\u0442\u0432\u0435\u0442 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0435\u0440\u0438\u0438! \u041d\u043e \u0434\u0430\u0436\u0435 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f <code>BlogLayout<\/code>, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>BlogIndexPage<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>fs.readdir()<\/code>.<\/em><\/p>\n<p>  <\/p>\n<p>\u041f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044e \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0435\u0440\u0435\u0432\u043e JSX, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">&lt;html>   &lt;head>...&lt;\/head>   &lt;body>     &lt;nav>       &lt;a href=\"\/\">Home&lt;\/a>       &lt;hr \/>     &lt;\/nav>     &lt;main>     &lt;section>       &lt;h1>Welcome to my blog&lt;\/h1>       &lt;div>         ...       &lt;\/div>     &lt;\/main>     &lt;footer>       &lt;hr \/>       &lt;p>         &lt;i>           (c) Jae Doe 2003         &lt;\/i>       &lt;\/p>     &lt;\/footer>   &lt;\/body> &lt;\/html><\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u0434\u0435\u0440\u0435\u0432\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 <code>JSON.stringify()<\/code> \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0443.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>renderJSXToClientJSX<\/code>. \u041e\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043a\u0443\u0441\u043e\u043a JSX \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0438 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f &#171;\u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c&#187; \u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 (\u043f\u0443\u0442\u0435\u043c \u0432\u044b\u0437\u043e\u0432\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432) \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e JSX, \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442\u0443.<\/p>\n<p>  <\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u043e \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u0445\u043e\u0436\u0430 \u043d\u0430 <code>renderJSXToHTML()<\/code>, \u043d\u043e \u0432\u043c\u0435\u0441\u0442\u043e HTML \u043e\u043d\u0430 \u043e\u0431\u0445\u043e\u0434\u0438\u0442 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u044b:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function renderJSXToClientJSX(jsx) {   if (     typeof jsx === \"string\" ||     typeof jsx === \"number\" ||     typeof jsx === \"boolean\" ||     jsx == null   ) {     \/\/ \u0421 \u044d\u0442\u0438\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e.     return jsx;   } else if (Array.isArray(jsx)) {     \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043c\u0430\u0441\u0441\u0438\u0432\u0430.     return Promise.all(jsx.map((child) => renderJSXToClientJSX(child)));   } else if (jsx !== null &amp;&amp; typeof jsx === \"object\") {     if (jsx.$$typeof === Symbol.for(\"react.element\")) {       if (typeof jsx.type === \"string\") {         \/\/ \u042d\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 (\u0442\u0430\u043a\u043e\u0439 \u043a\u0430\u043a &lt;div \/>).         \/\/ \u041f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u043c \u0435\u0433\u043e \u043f\u0440\u043e\u043f\u044b \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438\u0445 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 JSON.         return {           ...jsx,           props: await renderJSXToClientJSX(jsx.props),         };       } else if (typeof jsx.type === \"function\") {         \/\/ \u042d\u0442\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 React  (\u0442\u0430\u043a\u043e\u0439 \u043a\u0430\u043a &lt;Footer \/>).         \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0443 \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0435\u044e JSX.         const Component = jsx.type;         const props = jsx.props;         const returnedJsx = await Component(props);         return renderJSXToClientJSX(returnedJsx);         \/\/ \u041d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e.       } else throw new Error(\"Not implemented.\");     } else {       \/\/ \u042d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u043f\u044b \u0438\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0438\u0445).       \/\/ \u041f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439, \u0435\u0441\u043b\u0438 \u0432 \u043d\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f JSX.       return Object.fromEntries(         await Promise.all(           Object.entries(jsx).map(async ([propName, value]) => [             propName,             await renderJSXToClientJSX(value),           ])         )       );     }     \/\/ \u041d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e.   } else throw new Error(\"Not implemented\"); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c <code>sendJSX()<\/code> \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f <code>&lt;Router \/><\/code> \u0432 &#171;\u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 JSX&#187; \u043f\u0435\u0440\u0435\u0434 \u0435\u0433\u043e \u0441\u0442\u0440\u0438\u043d\u0433\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function sendJSX(res, jsx) {   const clientJSX = await renderJSXToClientJSX(jsx);   const clientJSXString = JSON.stringify(clientJSX, null, 2);   res.setHeader(\"Content-Type\", \"application\/json\");   res.end(clientJSXString); }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/competent-dawn-grmx8d?file=%2Fserver.js%3A1%2C1\" rel=\"nofollow noopener noreferrer\">\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435.<\/a><\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043b\u0438\u043a \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0441 \u0434\u0435\u0440\u0435\u0432\u043e\u043c, \u043f\u043e\u0445\u043e\u0436\u0438\u043c \u043d\u0430 HTML \u2014 \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043a \u0435\u0433\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e (diffing)!<\/p>\n<p>  <\/p>\n<blockquote><p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u043d\u0430\u0448\u0430 \u0446\u0435\u043b\u044c \u2014 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0435\u0447\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0435, \u043c\u043d\u043e\u0433\u043e\u0435 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0431\u0435\u0437 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f. \u0424\u043e\u0440\u043c\u0430\u0442 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u0435\u043d \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u043e\u0432, \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0445 RSC \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442. \u041a\u0430\u043a \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0435\u0439 HTML, \u043f\u043b\u043e\u0445\u043e, \u0447\u0442\u043e &#171;\u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f&#187; \u0432\u0435\u0441\u044c \u043e\u0442\u0432\u0435\u0442 \u0446\u0435\u043b\u0438\u043a\u043e\u043c. \u0412 \u0438\u0434\u0435\u0430\u043b\u0435 \u043d\u0430\u043c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0441\u0442\u0440\u0438\u043c\u0438\u0442\u044c JSX \u043f\u043e \u0447\u0430\u0441\u0442\u044f\u043c \u043f\u043e \u043c\u0435\u0440\u0435 \u0438\u0445 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u0438 \u0441\u043a\u043b\u0435\u0438\u0432\u0430\u0442\u044c \u0438\u0445 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435. \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0447\u0430\u0441\u0442\u0438 \u043e\u0431\u0449\u0435\u0433\u043e \u043c\u0430\u043a\u0435\u0442\u0430 (\u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a <code>&lt;html><\/code> \u0438 <code>&lt;nav><\/code>) \u0445\u043e\u0442\u044f \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u043e\u043d\u0438 \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c. \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432\u0441\u0435\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430 (screen) \u043d\u0430 \u043c\u0435\u0441\u0442\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0430\u0436\u043d\u043e\u0439, \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0430\u043a\u0435\u0442\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043a \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043c\u0430\u043a\u0435\u0442\u0430. \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f RSC \u043d\u0435 \u0441\u0442\u0440\u0430\u0434\u0430\u0435\u0442 \u043e\u0442 \u044d\u0442\u0438\u0445 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432, \u043d\u043e \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u043c \u0441\u0435\u0439\u0447\u0430\u0441 \u0432 \u0446\u0435\u043b\u044f\u0445 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043a\u043e\u0434\u0430.<\/p><\/blockquote>\n<p>  <\/p>\n<h3 id=\"shag-53-primenyaem-obnovleniya-jsx-na-kliente\">\u0428\u0430\u0433 5.3: \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f JSX \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435<\/h3>\n<p>  <\/p>\n<p>\u0421\u0442\u0440\u043e\u0433\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d React \u0434\u044f\u043b \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f JSX. \u041d\u0430\u0448\u0438 \u0443\u0437\u043b\u044b JSX \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a <code>&lt;nav><\/code> \u0438 <code>&lt;footer><\/code>. \u041c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u0441 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0435 \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 JSX. \u041e\u0434\u043d\u0430\u043a\u043e \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0431\u043e\u0433\u0430\u0442\u0430\u044f \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c React \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0432 HTML. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b React \u043c\u043e\u0433 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0443\u0437\u043b\u043e\u043c DOM, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043d \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b (\u0442\u0430\u043a\u043e\u0439 \u043a\u0430\u043a \u0443\u0437\u0435\u043b DOM, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u043c \u0438\u0437 HTML), \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c React \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 JSX, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u044d\u0442\u043e\u043c\u0443 \u0443\u0437\u043b\u0443 DOM. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u043e\u0434\u0440\u044f\u0434\u0447\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0441\u0438\u0442 \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u043d\u0430 \u043f\u043b\u0430\u043d \u0434\u043e\u043c\u0430 \u043f\u0435\u0440\u0435\u0434 \u0435\u0433\u043e \u0440\u0435\u043c\u043e\u043d\u0442\u043e\u043c. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u0422\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0436\u0435 React \u043e\u0431\u0445\u043e\u0434\u0438\u0442 DOM \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u043a\u0430\u043a\u0438\u0435 \u0447\u0430\u0441\u0442\u0438 JSX \u043a\u0430\u043a\u0438\u043c \u0443\u0437\u043b\u0430\u043c DOM \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 React \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043a \u0443\u0437\u043b\u0430\u043c DOM, \u0434\u0435\u043b\u0430\u044f \u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c\u0438, \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0438\u0445 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u041e\u043d\u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u0433\u0438\u0434\u0440\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b (hydrated), \u043a\u0430\u043a \u0440\u0430\u0441\u0442\u0435\u043d\u0438\u044f, \u043e\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u043e\u0442 \u0432\u043e\u0434\u044b.<\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u044b\u0447\u043d\u043e, \u0434\u043b\u044f \u0433\u0438\u0434\u0440\u0430\u0442\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0438, \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <a href=\"https:\/\/react.dev\/reference\/react-dom\/client\/hydrateRoot#usage\" rel=\"nofollow noopener noreferrer\">hydrateRoot<\/a> \u0441 \u0443\u0437\u043b\u043e\u043c DOM, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f React, \u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c JSX, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u043c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">hydrateRoot(document, &lt;App \/>);<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043d\u0435\u0442 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 (\u0442\u0430\u043a\u043e\u0433\u043e \u043a\u0430\u043a <code>&lt;App \/><\/code>). \u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u2014 \u044d\u0442\u043e \u043e\u0434\u0438\u043d \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u0443\u0441\u043e\u043a JSX \u0431\u0435\u0437 \u0435\u0434\u0438\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 React \u0432 \u043d\u0435\u043c. \u041e\u0434\u043d\u0430\u043a\u043e, \u0432\u0441\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e React, \u044d\u0442\u043e \u0434\u0435\u0440\u0435\u0432\u043e JSX, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c\u0443 HTML. \u0414\u0435\u0440\u0435\u0432\u043e &#171;\u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e JSX&#187; (\u0442\u0430\u043a\u043e\u0435 \u043a\u0430\u043a <code>&lt;html>...&lt;\/html><\/code>), \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u043d\u0430\u0443\u0447\u0438\u043b\u0438 \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0435\u0440, \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { hydrateRoot } from 'react-dom\/client';  const root = hydrateRoot(document, getInitialClientJSX());  function getInitialClientJSX() {   \/\/ TODO: \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0434\u0435\u0440\u0435\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e JSX &lt;html>...&lt;\/html>, \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0449\u0435\u0435 \u0441 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c HTML }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u044b\u043c, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0435\u0439\u0447\u0430\u0441 \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u043c JSX \u043d\u0435\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. React \u043f\u043e\u0447\u0442\u0438 \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e \u043e\u0431\u043e\u0439\u0434\u0435\u0442 \u0434\u0435\u0440\u0435\u0432\u043e DOM \u0438 \u0434\u0435\u0440\u0435\u0432\u043e JSX \u0438 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0443\u044e \u0435\u043c\u0443 \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0435\u0440\u0435\u0432\u0430.<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c, \u043f\u0440\u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043c\u044b \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c JSX \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c DOM \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/react.dev\/reference\/react-dom\/client\/hydrateRoot#updating-a-hydrated-root-component\" rel=\"nofollow noopener noreferrer\">root.render<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function navigate(pathname) {   currentPathname = pathname;   const clientJSX = await fetchClientJSX(pathname);   if (pathname === currentPathname) {     root.render(clientJSX);   } }  async function fetchClientJSX(pathname) {   \/\/ TODO: \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 JSX &lt;html>...&lt;\/html> \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0440\u043e\u0443\u0442\u0430 }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0438\u0447\u044c \u043d\u0430\u0448\u0435\u0439 \u0446\u0435\u043b\u0438 \u2014 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f DOM \u0442\u0430\u043a\u0436\u0435, \u043a\u0430\u043a \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u0434\u0435\u043b\u0430\u0435\u0442 React, \u0431\u0435\u0437 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u0438\u0445 \u0434\u0432\u0443\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<p>  <\/p>\n<h4 id=\"shag-531-poluchaem-jsx-ot-servera\">\u0428\u0430\u0433 5.3.1: \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c JSX \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430<\/h4>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 <code>fetchClientJSX()<\/code>, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0435\u0435 \u043b\u0435\u0433\u0447\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u043f\u043e\u043c\u043d\u0438\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430\u0448\u0430 \u043a\u043e\u043d\u0435\u0447\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 <code>?jsx<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function sendJSX(res, jsx) {   const clientJSX = await renderJSXToClientJSX(jsx);   const clientJSXString = JSON.stringify(clientJSX);   res.setHeader(\"Content-Type\", \"application\/json\");   res.end(clientJSXString); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043c\u044b \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u044d\u0442\u043e\u0439 \u0442\u043e\u0447\u043a\u0435 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043e\u0442\u0432\u0435\u0442 \u0432 <code>JSON.parse()<\/code> \u0434\u043b\u044f \u0435\u0433\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 JSX:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function fetchClientJSX(pathname) {   const response = await fetch(pathname + \"?jsx\");   const clientJSXString = await response.text();   const clientJSX = JSON.parse(clientJSXString);   return clientJSX; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u043e\u0442\u043a\u0440\u043e\u0435\u0442\u0435 <a href=\"https:\/\/codesandbox.io\/p\/sandbox\/vibrant-golick-x09dj7?file=%2Fclient.js\" rel=\"nofollow noopener noreferrer\">\u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435<\/a>, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u043f\u0440\u0438 \u043a\u043b\u0438\u043a\u0435 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 JSX \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0442\u0430\u043a\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">Objects are not valid as a React child (found: object with keys {type, key, ref, props, _owner, _store}).<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u043f\u043e\u0447\u0435\u043c\u0443 \u0442\u0430\u043a \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442. \u041e\u0431\u044a\u0435\u043a\u0442, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 <code>JSON.stringify()<\/code>, \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">{   $$typeof: Symbol.for(\"react.element\"),   type: 'html',   props: {     \/\/ ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 <code>JSON.parse()<\/code> \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>$$typeof<\/code> \u0438\u0441\u0447\u0435\u0437\u0430\u0435\u0442 \u043f\u0440\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">{   type: 'html',   props: {     \/\/ ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u0411\u0435\u0437 <code>$$typeof: Symbol.for(\"react.element\")<\/code> React \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043e\u0442\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u0430\u043a \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 \u0443\u0437\u0435\u043b JSX.<\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0437\u0430\u0449\u0438\u0442\u044b. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e React \u043e\u0442\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b JSON, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 \u0441\u0435\u0442\u0438, \u043a\u0430\u043a \u0442\u0435\u0433\u0438 JSX. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 <code>symbol<\/code> (\u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a <code>Symbol.for('react.element')<\/code>) \u0443\u0434\u0430\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>JSON.stringify()<\/code>. \u042d\u0442\u043e \u0437\u0430\u0449\u0438\u0449\u0430\u0435\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043e\u0442 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 JSX, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0431\u044b\u043b \u044f\u0432\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u043d \u043a\u043e\u0434\u043e\u043c \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u044d\u0442\u0438 \u0443\u0437\u043b\u044b JSX \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043d\u0430\u043c\u0438 (\u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435), \u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0438\u0445 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>$$typeof: Symbol.for(\"react.element\")<\/code>, \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0435\u0433\u043e \u043d\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u043e\u0441\u0442\u044c.<\/p>\n<p>  <\/p>\n<p>\u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u044d\u0442\u043e \u043b\u0435\u0433\u043a\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c. <code>JSON.stringify()<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e-\u0437\u0430\u043c\u0435\u043d\u0438\u0442\u0435\u043b\u044c (replacer function), \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0443\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e JSON. \u0417\u0430\u043c\u0435\u043d\u044f\u0435\u043c <code>Symbol.for('react.element')<\/code> \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 <code>\"$RE\"<\/code> \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function sendJSX(res, jsx) {   \/\/ ...   const clientJSXString = JSON.stringify(clientJSX, stringifyJSX);   \/\/ ... }  function stringifyJSX(key, value) {   if (value === Symbol.for(\"react.element\")) {     \/\/ \u041c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443.     return \"$RE\"; \/\/ \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u044e\u0431\u044b\u043c. \u042f \u0432\u044b\u0431\u0440\u0430\u043b RE \u043a\u0430\u043a \u0430\u0431\u0431\u0440\u0435\u0432\u0438\u0430\u0442\u0443\u0440\u0443 React Element.   } else if (typeof value === \"string\" &amp;&amp; value.startsWith(\"$\")) {     \/\/ \u0412\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u043e\u0432 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d $ \u043a \u0441\u0442\u0440\u043e\u043a\u0435, \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0435\u0439\u0441\u044f \u0441 $.     return \"$\" + value;   } else {     return value;   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c <code>JSON.parse()<\/code> &#171;\u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043e\u0436\u0438\u0432\u043b\u0435\u043d\u0438\u044f&#187; (reviver function) \u0434\u043b\u044f \u0437\u0430\u043c\u0435\u043d\u044b <code>\"$RE\"<\/code> \u043d\u0430 <code>Symbol.for('react.element')<\/code> \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function fetchClientJSX(pathname) {   \/\/ ...   const clientJSX = JSON.parse(clientJSXString, parseJSX);   \/\/ ... }  function parseJSX(key, value) {   if (value === \"$RE\") {     \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0430\u0440\u043a\u0435\u0440, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.     \/\/ \u0412\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0441\u0438\u043c\u0432\u043e\u043b \u0434\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u0438 JSX \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f React.     return Symbol.for(\"react.element\");   } else if (typeof value === \"string\" &amp;&amp; value.startsWith(\"$$\")) {     \/\/ \u042d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430, \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0430\u044f\u0441\u044f \u0441 $. \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 $, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c.     return value.slice(1);   } else {     return value;   } }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/silly-silence-v7lq4p?file=%2Fclient.js%3A1%2C1\" rel=\"nofollow noopener noreferrer\">\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435.<\/a><\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a JSX \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435!<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0432\u0435\u0441\u0442\u0438 \u043a\u0430\u043a\u043e\u0435-\u043d\u0438\u0431\u0443\u0434\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u0438\u043d\u043f\u0443\u0442 \u0438 \u043a\u043b\u0438\u043a\u043d\u0443\u0442\u044c \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435, \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438\u043d\u043f\u0443\u0442\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0439, \u043a\u0440\u043e\u043c\u0435 \u0441\u0430\u043c\u043e\u0439 \u043f\u0435\u0440\u0432\u043e\u0439. \u042d\u0442\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e React \u043d\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c JSX \u0434\u043b\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u043c\u0443 HTML.<\/p>\n<p>  <\/p>\n<h4 id=\"shag-532-preobrazuem-nachalnyy-jsx-v-html\">\u0428\u0430\u0433 5.3.2: \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 JSX \u0432 HTML<\/h4>\n<p>  <\/p>\n<p>\u0423 \u043d\u0430\u0441 \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u043d\u0435\u0434\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const root = hydrateRoot(document, getInitialClientJSX());  function getInitialClientJSX() {   return null; \/\/ TODO }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0433\u0438\u0434\u0440\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0443\u0437\u0435\u043b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e JSX, \u043d\u043e \u043e\u0442\u043a\u0443\u0434\u0430 \u0435\u0433\u043e \u0432\u0437\u044f\u0442\u044c?<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0448\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0432 HTML, \u043d\u043e \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0445 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0439 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c React \u043e \u0442\u043e\u043c, \u043a\u0430\u043a\u0438\u043c \u0431\u044b\u043b \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 JSX \u0434\u043b\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u0418\u043d\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u0443\u044e \u0440\u0435\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e HTML, \u043d\u043e \u0442\u0430\u043a\u043e\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0432\u043e \u0432\u0441\u0435\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u044f\u0432\u044f\u0442\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u044d\u0442\u043e\u0439 \u0441\u0435\u0440\u0438\u0438. \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u0445\u043e\u0442\u0438\u043c \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0435\u0433\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043d\u0435\u043d\u0443\u0436\u043d\u043e\u043c\u0443 \u0432\u043e\u0434\u043e\u043f\u0430\u0434\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 (waterfall).<\/p>\n<p>  <\/p>\n<p>\u0412 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e\u043c SSR \u0441 React \u043c\u044b \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0441 \u043f\u043e\u0445\u043e\u0436\u0435\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439, \u043d\u043e \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u043b\u044f \u0433\u0438\u0434\u0440\u0430\u0442\u0430\u0446\u0438\u0438 \u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e JSX \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0434\u0430\u043d\u043d\u044b\u0435. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 (\u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435, \u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u043a\u043e\u0434, \u043d\u043e \u0443 \u043d\u0430\u0441 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u0442 \u043a\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u043d\u0430\u0435\u0442, \u043a\u0430\u043a \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 JSX.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0438\u0437 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430 \u0441 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c JSX \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0447\u0435\u0440\u0435\u0437 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const root = hydrateRoot(document, getInitialClientJSX());  function getInitialClientJSX() {   const clientJSX = JSON.parse(window.__INITIAL_CLIENT_JSX_STRING__, reviveJSX);   return clientJSX; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>sendHTML<\/code> \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u0432\u0438\u0434\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e JSX \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e JSX \u0432 \u043a\u043e\u043d\u0435\u0446 HTML:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function sendHTML(res, jsx) {   let html = await renderJSXToHTML(jsx);    \/\/ \u0421\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u043c JSX \u043f\u043e\u0441\u043b\u0435 HTML \u0432\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 (paint):   const clientJSX = await renderJSXToClientJSX(jsx);   const clientJSXString = JSON.stringify(clientJSX, stringifyJSX);   html += `&lt;script>window.__INITIAL_CLIENT_JSX_STRING__ = `;   html += JSON.stringify(clientJSXString).replace(\/&lt;\/g, \"\\\\u003c\");   html += `&lt;\/script>`;   \/\/ ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0432\u043d\u043e\u0441\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e <a href=\"https:\/\/codesandbox.io\/p\/sandbox\/vigorous-lichterman-i30pi4?file=%2Fserver.js%3A200%2C1-211%2C17\" rel=\"nofollow noopener noreferrer\">\u043c\u0435\u043b\u043a\u0438\u0445 \u043f\u0440\u0430\u0432\u043e\u043a<\/a> \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 HTML \u0434\u043b\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u0443\u0437\u043b\u043e\u0432, \u0447\u0442\u043e\u0431\u044b React \u043c\u043e\u0433 \u0438\u0445 \u0433\u0438\u0434\u0440\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/vigorous-lichterman-i30pi4?file=%2Fserver.js%3A1%2C1\" rel=\"nofollow noopener noreferrer\">\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435.<\/a><\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0435 \u0432 \u0438\u043d\u043f\u0443\u0442, \u043d\u0435 \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f\u043c\u0438.<\/p>\n<p>  <\/p>\n<div class=\"oembed\">\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/64895af0ae851501c52b9b89\" data-style=\"\" id=\"64895af0ae851501c52b9b89\" width=\"\"><\/div>\n<\/div>\n<p>  <\/p>\n<p>\u041d\u0430\u0448\u0430 \u0446\u0435\u043b\u044c \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442\u0430! \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0434\u0435\u043b\u043e \u043d\u0435 \u0432 \u044d\u0442\u043e\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0438\u043d\u043f\u0443\u0442\u0435 \u2014 \u0432\u0430\u0436\u043d\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043d\u0430 \u043c\u0435\u0441\u0442\u0435 \u043d\u0430 \u043b\u044e\u0431\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u043b\u044e\u0431\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<blockquote><p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f RSC \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 JSX \u0432 HTML, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0436\u043d\u044b\u0445 \u043e\u0442\u043b\u0438\u0447\u0438\u0439. \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f RSC \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0447\u0430\u0441\u0442\u0438 JSX \u043f\u043e \u043c\u0435\u0440\u0435 \u0438\u0445 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438, \u0430 \u043d\u0435 \u043e\u0434\u0438\u043d \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u0443\u0441\u043e\u043a \u0432 \u043a\u043e\u043d\u0446\u0435. \u0413\u0438\u0434\u0440\u0430\u0442\u0430\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u2014 React \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 JSX, \u043d\u0435 \u043e\u0436\u0438\u0434\u0430\u044f \u043f\u0440\u0438\u0431\u044b\u0442\u0438\u044f \u0432\u0441\u0435\u0445 \u0447\u0430\u0441\u0442\u0435\u0439. RSC \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043a\u0430\u043a \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0435 (\u043f\u0440\u0438\u043c. \u043f\u0435\u0440.: \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u0430 <code>\"use client\"<\/code> \u0432 Next.js). \u0422\u0430\u043a\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u044f\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0432 HTML, \u043d\u043e \u0438\u0445 \u043a\u043e\u0434 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u0431\u043e\u0440\u043a\u0443 (bundle) \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u0414\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e JSON \u0434\u043b\u044f \u0438\u0445 \u043f\u0440\u043e\u043f\u043e\u0432. \u0412 \u0431\u0443\u0434\u0443\u0449\u0435\u043c React \u043c\u043e\u0436\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u044b \u0434\u043b\u044f \u0434\u0435\u0434\u0443\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u0438 (deduplication) \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043c\u0435\u0436\u0434\u0443 HTML \u0438 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439.<\/p><\/blockquote>\n<p>  <\/p>\n<h2 id=\"shag-6-navodim-poryadok\">\u0428\u0430\u0433 6: \u043d\u0430\u0432\u043e\u0434\u0438\u043c \u043f\u043e\u0440\u044f\u0434\u043e\u043a<\/h2>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u043c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u0434\u0430 \u043a \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c\u0443 RSC. \u041c\u044b \u043f\u043e\u043a\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u044b \u0432\u0440\u043e\u0434\u0435 \u0441\u0442\u0440\u0438\u043c\u0438\u043d\u0433\u0430, \u043d\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432 \u0438 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043c\u0441\u044f \u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439.<\/p>\n<p>  <\/p>\n<h3 id=\"shag-61-vypolnyaem-deduplikaciyu-raboty\">\u0428\u0430\u0433 6.1: \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0434\u0435\u0434\u0443\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u0440\u0430\u0431\u043e\u0442\u044b<\/h3>\n<p>  <\/p>\n<p>\u0412\u0441\u043f\u043e\u043c\u043d\u0438\u043c, \u043a\u0430\u043a \u043c\u044b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 HTML:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function sendHTML(res, jsx) {   \/\/ &lt;Router \/> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \"&lt;html>...&lt;\/html>\" (\u0441\u0442\u0440\u043e\u043a\u0443):   let html = await renderJSXToHTML(jsx);    \/\/ &lt;Router \/> \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0432 &lt;html>...&lt;\/html> (\u043e\u0431\u044a\u0435\u043a\u0442):   const clientJSX = await renderJSXToClientJSX(jsx);<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e <code>jsx<\/code> \u0437\u0434\u0435\u0441\u044c \u2014 \u044d\u0442\u043e <code>&lt;Router url=\"https:\/\/localhost:3000\" \/><\/code>.<\/p>\n<p>  <\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>renderJSXToHTML()<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>Router<\/code> \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u043e\u043a\u0438 HTML. \u041d\u043e \u043d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 JSX, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u043b\u0435\u0434 \u0437\u0430 \u044d\u0442\u0438\u043c \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>renderJSXToClientJSX()<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043d\u043e\u0432\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>Router<\/code> \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u0432\u0430\u0436\u0434\u044b. \u042d\u0442\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043c\u0435\u0434\u043b\u044f\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443, \u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043a \u0440\u0430\u0437\u043d\u044b\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c \u0432\u044b\u0437\u043e\u0432\u0430 \u044d\u0442\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 <code>Feed<\/code> (\u043d\u043e\u0432\u043e\u0441\u0442\u043d\u0430\u044f \u043b\u0435\u043d\u0442\u0430). \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445 (data flow) \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u043e\u0441\u043c\u044b\u0441\u043b\u0435\u043d.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u0435\u0441\u043b\u0438 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e JSX?<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function sendHTML(res, jsx) {   \/\/ 1. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c &lt;Router \/> \u0432 &lt;html>...&lt;\/html> (\u043e\u0431\u044a\u0435\u043a\u0442):   const clientJSX = await renderJSXToClientJSX(jsx);<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f. \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c HTML \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async function sendHTML(res, jsx) {   \/\/ 1. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c &lt;Router \/> \u0432 &lt;html>...&lt;\/html> (\u043e\u0431\u044a\u0435\u043a\u0442):   const clientJSX = await renderJSXToClientJSX(jsx);   \/\/ 2. \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u044d\u0442\u043e\u0442 &lt;html>...&lt;\/html> \u0432 \"&lt;html>...&lt;\/html>\" (\u0441\u0442\u0440\u043e\u043a\u0443):   let html = await renderJSXToHTML(clientJSX);   \/\/ ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437.<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/serverless-morning-ith5fg?file=%2Fserver.js\" rel=\"nofollow noopener noreferrer\">\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435.<\/a><\/p>\n<p>  <\/p>\n<h3 id=\"shag-62-ispolzuem-react-dlya-renderinga-html\">\u0428\u0430\u0433 6.2: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c React \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 HTML<\/h3>\n<p>  <\/p>\n<p>\u041a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f <code>renderJSXToHTML()<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u043b\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043a\u0430\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430\u0448\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u041e\u0434\u043d\u0430\u043a\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u043d\u0435\u0435 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e JSX, <code>renderJSXToHTML()<\/code> \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 React <a href=\"https:\/\/react.dev\/reference\/react-dom\/server\/renderToString\" rel=\"nofollow noopener noreferrer\">renderToString<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { renderToString } from 'react-dom\/server';  \/\/ ...  async function sendHTML(res, jsx) {   const clientJSX = await renderJSXToClientJSX(jsx);   let html = renderToString(clientJSX);   \/\/ ...<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/vigorous-tess-ykpez3?file=%2Fserver.js%3A189%2C1\" rel=\"nofollow noopener noreferrer\">\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435.<\/a><\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u043c \u043a\u043e\u0434\u043e\u043c. \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u043e\u0432\u044b\u0445 \u0444\u0438\u0447 (\u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b), \u043c\u044b \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b React, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a <code>renderToString()<\/code> \u0438\u043b\u0438 <code>hydrateRoot()<\/code>. \u041e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 React \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>renderToString()<\/code> \u0438 <code>hydrateRoot()<\/code> \u0441 \u043a\u043e\u0440\u043d\u0435\u0432\u044b\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c <code>&lt;App \/><\/code>. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c (evaluate) &#171;\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0435&#187; \u0434\u0435\u0440\u0435\u0432\u043e JSX \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>renderJSXToClientJSX()<\/code> \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c React.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f <code>renderToString()<\/code> \u0438 <code>hydrateRoot()<\/code> <code>Router<\/code>, <code>BlogIndexPage<\/code> \u0438 <code>Footer<\/code> \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0438. \u0412\u044b\u0437\u043e\u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0432 \u0434\u0435\u0440\u0435\u0432\u0435 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u0438\u043c\u0438 JSX.<\/p>\n<p>  <\/p>\n<h3 id=\"shag-63-razdelyaem-server-na-dva\">\u0428\u0430\u0433 6.3: \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 \u0434\u0432\u0430<\/h3>\n<p>  <\/p>\n<p>\u041d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0448\u0430\u0433\u0435 \u043c\u044b \u043e\u0442\u0434\u0435\u043b\u0438\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043e\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 HTML:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0441\u043d\u0430\u0447\u0430\u043b\u0430 <code>renderJSXToClientJSX()<\/code> \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e JSX;<\/li>\n<li>\u0437\u0430\u0442\u0435\u043c <code>renderToString()<\/code> \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 JSX \u0432 HTML.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u0438 \u0448\u0430\u0433\u0438 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b, \u0438\u0445 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435. \u0420\u0430\u0437\u0434\u0435\u043b\u0438\u043c <code>server.js<\/code> \u043d\u0430 \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/agitated-swartz-4hs4v1?file=%2Fserver%2Frsc.js\" rel=\"nofollow noopener noreferrer\">server\/rsc.js<\/a> \u2014 \u044d\u0442\u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u0415\u0441\u043b\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043e\u0431\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u043a \u0411\u0414, \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0435\u0433\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0431\u043b\u0438\u0437\u043a\u043e \u043a \u0434\u0430\u0442\u0430-\u0446\u0435\u043d\u0442\u0440\u0443 \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438;<\/li>\n<li><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/agitated-swartz-4hs4v1?file=%2Fserver%2Fssr.js\" rel=\"nofollow noopener noreferrer\">server\/ssr.js<\/a> \u2014 \u044d\u0442\u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c HTML. \u041e\u043d \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f (edge) \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 HTML \u0438 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u042d\u0442\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0432 <code>package.json<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"json\">\"scripts\": {   \"start\": \"concurrently \\\"npm run start:ssr\\\" \\\"npm run start:rsc\\\"\",   \"start:rsc\": \"nodemon -- --experimental-loader .\/node-jsx-loader.js .\/server\/rsc.js\",   \"start:ssr\": \"nodemon -- --experimental-loader .\/node-jsx-loader.js .\/server\/ssr.js\" },<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043e\u043d\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435, \u043d\u043e \u043c\u044b \u0432\u043f\u043e\u043b\u043d\u0435 \u043c\u043e\u0436\u0435\u043c &#171;\u0445\u043e\u0441\u0442\u0438\u0442\u044c&#187; (host) \u0438\u0445 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440 RSC \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u041e\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0438\u0445 JSX:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ server\/rsc.js createServer(async (req, res) => {   try {     const url = new URL(req.url, `http:\/\/${req.headers.host}`);     await sendJSX(res, &lt;Router url={url} \/>);   } catch (err) {     console.error(err);     res.statusCode = err.statusCode ?? 500;     res.end();   } }).listen(8081);  function Router({ url }) {   \/\/ ... }  \/\/ ... \/\/ \u0414\u0440\u0443\u0433\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \/\/ ...  async function sendJSX(res, jsx) {   \/\/ ... }  function stringifyJSX(key, value) {   \/\/ ... }  async function renderJSXToClientJSX(jsx) {   \/\/ ... }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440 SSR \u2014 \u044d\u0442\u043e \u0441\u0435\u0440\u0432\u0435\u0440, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043e\u0431\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438. \u041e\u043d \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 RSC \u0437\u0430 JSX \u0438 \u043b\u0438\u0431\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u044d\u0442\u043e\u0442 JSX \u043a\u0430\u043a \u0441\u0442\u0440\u043e\u043a\u0443 (\u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438), \u043b\u0438\u0431\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0435\u0433\u043e \u0432 HTML (\u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438):<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ server\/ssr.js createServer(async (req, res) => {   try {     const url = new URL(req.url, `http:\/\/${req.headers.host}`);     if (url.pathname === \"\/client.js\") {       \/\/ ...     }     \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 JSX \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 RSC     const response = await fetch(\"http:\/\/127.0.0.1:8081\" + url.pathname);     if (!response.ok) {       res.statusCode = response.status;       res.end();       return;     }     const clientJSXString = await response.text();     if (url.searchParams.has(\"jsx\")) {       \/\/ \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u044d\u0442\u043e\u0442 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b\u0439 JSX \u043a\u0430\u043a \u0435\u0441\u0442\u044c       res.setHeader(\"Content-Type\", \"application\/json\");       res.end(clientJSXString);     } else {       \/\/ \u041f\u0440\u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0434\u0435\u0440\u0435\u0432\u043e \u0432 HTML       const clientJSX = JSON.parse(clientJSXString, parseJSX);       let html = renderToString(clientJSX);       html += `&lt;script>window.__INITIAL_CLIENT_JSX_STRING__ = `;       html += JSON.stringify(clientJSXString).replace(\/&lt;\/g, \"\\\\u003c\");       html += `&lt;\/script>`;       \/\/ ...       res.setHeader(\"Content-Type\", \"text\/html\");       res.end(html);     }   } catch (err) {     \/\/ ...   } }).listen(8080);<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/agitated-swartz-4hs4v1?file=%2Fserver%2Fssr.js\" rel=\"nofollow noopener noreferrer\">\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0435.<\/a><\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 RSC \u0438 &#171;\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043c\u0438\u0440\u043e\u043c&#187; (SSR \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c) \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u043d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0439 \u0441\u0435\u0440\u0438\u0438. \u041f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0441\u0442\u0430\u043d\u0443\u0442 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u043c\u0438 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u044f\u0445, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043d\u0430\u0447\u043d\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c &#171;\u0444\u0438\u0447\u0438&#187; (features) \u0432 \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043c\u0438\u0440\u043e\u0432, \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u044f \u0438\u0445 \u0432\u043c\u0435\u0441\u0442\u0435.<\/p>\n<p>  <\/p>\n<p><em>\u0421\u0442\u0440\u043e\u0433\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c RSC \u0438 SSR \u0432\u043d\u0443\u0442\u0440\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u043d\u043e \u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438. \u042d\u0442\u043e \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u0430\u044f \u0442\u0435\u043c\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u0440\u0430\u043c\u043a\u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438.<\/em><\/p>\n<p>  <\/p>\n<h2 id=\"rezyume\">\u0420\u0435\u0437\u044e\u043c\u0435<\/h2>\n<p>  <\/p>\n<p>\u041d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u044d\u0442\u043e \u0432\u0441\u0435!<\/p>\n<p>  <\/p>\n<p>\u041c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u043d\u043e, \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/agitated-swartz-4hs4v1?file=%2Fserver%2Frsc.js\" rel=\"nofollow noopener noreferrer\">server\/rsc.js<\/a> \u2014 160 \u0441\u0442\u0440\u043e\u043a, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 80 \u2014 \u043d\u0430\u0448\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b;<\/li>\n<li><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/agitated-swartz-4hs4v1?file=%2Fserver%2Fssr.js\" rel=\"nofollow noopener noreferrer\">server\/ssr.js<\/a> \u2014 60 \u0441\u0442\u0440\u043e\u043a;<\/li>\n<li><a href=\"https:\/\/codesandbox.io\/p\/sandbox\/agitated-swartz-4hs4v1?file=%2Fclient.js%3A1%2C1\" rel=\"nofollow noopener noreferrer\">client.js<\/a> \u2014 60 \u0441\u0442\u0440\u043e\u043a.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0445 \u0438\u0437\u0443\u0447\u0438\u0442\u0435. \u0414\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u043d\u0430\u0440\u0438\u0441\u0443\u0435\u043c \u043f\u0430\u0440\u043e\u0447\u043a\u0443 \u0441\u0445\u0435\u043c.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/eq\/z1\/nm\/eqz1nmo51fp7bs_ozis-oim5d2k.png\" data-src=\"https:\/\/habrastorage.org\/webt\/eq\/z1\/nm\/eqz1nmo51fp7bs_ozis-oim5d2k.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0410 \u0432\u043e\u0442 \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/q-\/xx\/9k\/q-xx9kg5nycxvi0pqjhtkwzjju4.png\" data-src=\"https:\/\/habrastorage.org\/webt\/q-\/xx\/9k\/q-xx9kg5nycxvi0pqjhtkwzjju4.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c\u0441\u044f \u0441 \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u0435\u0439:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c <em>\u0441\u0435\u0440\u0432\u0435\u0440 React<\/em> (\u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e <em>\u0441\u0435\u0440\u0432\u0435\u0440<\/em>) \u0434\u043b\u044f \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 RSC. \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u044d\u0442\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435 (\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u044d\u0442\u043e \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b), \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f <em>\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438<\/em>;<\/li>\n<li>\u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c <em>\u043a\u043b\u0438\u0435\u043d\u0442 React<\/em> (\u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e <em>\u043a\u043b\u0438\u0435\u043d\u0442<\/em>) \u0434\u043b\u044f \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0440\u0435\u0434\u044b, \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u044e\u0449\u0435\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c React. \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, <a href=\"https:\/\/github.com\/reactwg\/server-components\/discussions\/4\" rel=\"nofollow noopener noreferrer\">SSR \u2014 \u044d\u0442\u043e \u043a\u043b\u0438\u0435\u043d\u0442 React<\/a>, \u043a\u0430\u043a \u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440. \u041c\u044b \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u2014 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u044b \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u2014 \u043d\u043e, \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u043f\u043e\u0439\u043b\u0435\u0440\u0430, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u0445 <em>\u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438<\/em>.<\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"vyzovy\">\u0412\u044b\u0437\u043e\u0432\u044b<\/h2>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0447\u0442\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0435 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0438\u043b\u043e \u0432\u0430\u0448\u0435 \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u0441\u0442\u0432\u043e, \u043f\u043e\u0438\u0433\u0440\u0430\u0439\u0442\u0435 \u0441 <a href=\"https:\/\/codesandbox.io\/p\/sandbox\/agitated-swartz-4hs4v1?file=%2Fserver%2Frsc.js\" rel=\"nofollow noopener noreferrer\">\u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0434\u0435\u0439 \u0434\u043b\u044f \u0432\u043e\u043f\u043b\u043e\u0449\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u0444\u043e\u043d\u043e\u0432\u044b\u0439 \u0446\u0432\u0435\u0442 \u043a <code>&lt;body><\/code> \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 (transition) \u0434\u043b\u044f \u043d\u0435\u0433\u043e. \u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438 \u0444\u043e\u043d\u043e\u0432\u044b\u0439 \u0446\u0432\u0435\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f;<\/li>\n<li>\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 <a href=\"https:\/\/react.dev\/reference\/react\/Fragment\" rel=\"nofollow noopener noreferrer\">\u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043e\u0432 (&lt;>)<\/a> \u0432 \u0440\u0435\u043d\u0434\u0435\u0440\u0435\u0440\u0435 RSC. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0445\u0432\u0430\u0442\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430, \u043d\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c, \u043a\u0443\u0434\u0430 \u0438\u0445 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0438 \u0447\u0442\u043e \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0434\u0435\u043b\u0430\u0442\u044c;<\/li>\n<li>\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442\u044b \u0431\u043b\u043e\u0433\u0430 \u043a\u0430\u043a markdown \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 <code>&lt;Markdown><\/code> \u0438\u0437 \u043f\u0430\u043a\u0435\u0442\u0430 <code>react-markdown<\/code>. \u0414\u0430, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c;<\/li>\n<li>\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>&lt;Markdown><\/code> \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0435\u0433\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>Image<\/code> \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u043a\u0430\u043a <code>&lt;Markdown components={{ img: Image }}><\/code>. \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>Image<\/code>, \u0438\u0437\u043c\u0435\u0440\u044f\u044e\u0449\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f (\u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u0430\u043a\u0435\u0442 NPM) \u2014 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e\u0449\u0438\u0439 <code>width<\/code> \u0438 <code>height<\/code>;<\/li>\n<li>\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0440\u0430\u0437\u0434\u0435\u043b \u0441 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u043c\u0438 \u043a \u043f\u043e\u0441\u0442\u0443. \u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0432 \u0444\u0430\u0439\u043b\u0435 JSON \u043d\u0430 \u0434\u0438\u0441\u043a\u0435. \u0414\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f <code>&lt;form><\/code>. \u041a\u0440\u043e\u043c\u0435 \u044d\u0442\u043e\u0433\u043e, \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0432 <code>client.js<\/code> \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0444\u043e\u0440\u043c\u044b \u0438 \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u041f\u043e\u0441\u043b\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0444\u043e\u0440\u043c\u044b \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 JSX \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432;<\/li>\n<li>\u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 &#171;\u041d\u0430\u0437\u0430\u0434&#187; \u0441\u0435\u0439\u0447\u0430\u0441 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u0441\u0432\u0435\u0436\u0435\u0433\u043e JSX. \u0418\u0437\u043c\u0435\u043d\u0438\u0442\u0435 \u043b\u043e\u0433\u0438\u043a\u0443 \u0432 <code>client.js<\/code> \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f &#171;\u0412\u043f\u0435\u0440\u0435\u0434\/\u041d\u0430\u0437\u0430\u0434&#187; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0430 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043e\u0442\u0432\u0435\u0442\u044b, \u043d\u043e \u043a\u043b\u0438\u043a \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u043b \u0441\u0432\u0435\u0436\u0438\u0439 \u043e\u0442\u0432\u0435\u0442. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u044c\u0441\u044f \u043a \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u043c\u0443 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044e \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430;<\/li>\n<li>\u043f\u0440\u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u043f\u043e\u0441\u0442\u0430\u043c\u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0435\u0441\u044c \u0438\u0445 JSX. \u042d\u0442\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u2014 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0443\u0430\u043b\u044c\u043d\u043e, \u044d\u0442\u043e \u0434\u0432\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u0441\u0442\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u043c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u043f\u043e\u0441\u0442\u0443 \u0438 \u043a\u043b\u0438\u043a\u043d\u0443\u043b\u0438 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0441\u0442, \u043c\u044b \u043d\u0435 \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0438\u043d\u043f\u0443\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0442\u043e\u043c \u0436\u0435 \u043c\u0435\u0441\u0442\u0435. \u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443? (\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430: \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>Router<\/code> \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 URL \u043a\u0430\u043a \u0440\u0430\u0437\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043e\u0431\u0435\u0440\u043d\u0443\u0432 <code>{page}<\/code> \u0432\u043e \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c. \u0417\u0430\u0442\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u044d\u0442\u043e &#171;\u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c&#187; \u043d\u0435 \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435 \u043f\u043e \u0441\u0435\u0442\u0438);<\/li>\n<li>\u0444\u043e\u0440\u043c\u0430\u0442 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 JSX \u0441\u0435\u0439\u0447\u0430\u0441 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u043d\u044b\u0439. \u0415\u0441\u0442\u044c \u0438\u0434\u0435\u0438, \u043a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0433\u043e \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u044b\u043c? \u041c\u043e\u0436\u043d\u043e \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a RSC, \u0442\u0430\u043a\u043e\u0439 \u043a\u0430\u043a Next.js App Router \u0438\u043b\u0438 \u043d\u0430\u0448\u0435 <a href=\"https:\/\/github.com\/reactjs\/server-components-demo\" rel=\"nofollow noopener noreferrer\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0434\u0435\u043c\u043e RSC<\/a> \u0434\u043b\u044f \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0435\u043d\u0438\u044f. \u0414\u0430\u0436\u0435 \u0431\u0435\u0437 \u0441\u0442\u0440\u0438\u043c\u0438\u043d\u0433\u0430, \u0431\u044b\u043b\u043e \u0431\u044b \u0437\u0434\u043e\u0440\u043e\u0432\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b JSX \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c;<\/li>\n<li>\u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0432\u044b \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u041a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c? \u0421 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c?<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0420\u0430\u0437\u0432\u043b\u0435\u043a\u0430\u0439\u0442\u0435\u0441\u044c!<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/741604\/\"> https:\/\/habr.com\/ru\/articles\/741604\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/jc\/hw\/st\/jchwst6a3nwlxlscnmuw5tdhmry.png\" data-src=\"https:\/\/habrastorage.org\/webt\/jc\/hw\/st\/jchwst6a3nwlxlscnmuw5tdhmry.png\"\/>  <\/p>\n<p>  \u0412 \u044d\u0442\u043e\u043c \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u043c &#171;\u0433\u043b\u0443\u0431\u043e\u043a\u043e\u043c \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0438&#187; (deep dive) \u043c\u044b \u0441 \u043d\u0443\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e <a href=\"https:\/\/github.com\/reactjs\/rfcs\/blob\/main\/text\/0188-server-components.md\" rel=\"nofollow noopener noreferrer\">\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 React<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0442\u0440\u0435\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 (\u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u043f\u043e\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0430).<\/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-348761","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/348761","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=348761"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/348761\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=348761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=348761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=348761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}