{"id":319264,"date":"2021-03-09T15:01:13","date_gmt":"2021-03-09T15:01:13","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=319264"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=319264","title":{"rendered":"\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 React REST API \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f + TypeScript + Styled-Components"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0414\u043e\u0431\u0440\u043e\u0433\u043e %\u0432\u0440\u0435\u043c\u044f_\u0441\u0443\u0442\u043e\u043a, \u0445\u0430\u0431\u0440\u043e\u0432\u0447\u0430\u043d\u0435!<\/p>\n<p>\u041a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u0441\u0442\u0430\u0442\u044c\u0438 \u044f \u0435\u0449\u0435 \u043d\u0435 \u043f\u0438\u0441\u0430\u043b, \u043e\u043f\u044b\u0442\u0430 \u0432 \u044d\u0442\u043e\u043c \u043d\u0435\u0442 \u043e\u0442 \u0441\u043b\u043e\u0432\u0430 \u0441\u043e\u0432\u0441\u0435\u043c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043d\u0435 \u0441\u0443\u0434\u0438\u0442\u0435 \u0441\u0442\u0440\u043e\u0433\u043e \u0438 \u043f\u0440\u043e\u0448\u0443 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f, \u0435\u0441\u043b\u0438 \u0433\u0434\u0435-\u0442\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0443 \u043e\u0448\u0438\u0431\u043a\u0438. <\/p>\n<p>\u042d\u0442\u043e \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u043e\u0432\u044b\u0439 \u043e\u043f\u044b\u0442, \u043c\u043d\u0435 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u0435\u0449\u0435 \u043d\u0435 \u0434\u043e\u0432\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u0438 \u043d\u0430\u0440\u0430\u0431\u043e\u0442\u043a\u0430\u043c\u0438 \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e\u043c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/991\/8e8\/bd6\/9918e8bd6070ec15bb587627bb3e0bac.png\" width=\"998\" height=\"562\"><figcaption><\/figcaption><\/figure>\n<h2>\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435<\/h2>\n<p>\u041a\u043e\u0433\u0434\u0430 \u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0430\u043b \u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 React, \u043c\u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0438\u0441\u043a\u0430\u0442\u044c, \u0438 \u0438\u0441\u043a\u0430\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e-\u0442\u0430\u043a\u0438 \u0434\u043e\u043b\u0433\u043e, \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043c\u043e\u0433\u043b\u0430 \u0431\u044b \u043c\u043d\u0435 \u0433\u0440\u0430\u043c\u043e\u0442\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043c\u043e\u0438\u0445 \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432, \u043d\u043e \u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0431\u044b\u043b\u043e \u043c\u0430\u043b\u043e.<\/p>\n<p>\u041a\u0442\u043e-\u0442\u043e \u0441\u043e\u0432\u0435\u0442\u043e\u0432\u0430\u043b \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043b\u043e\u0441\u043a\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u0434\u043b\u044f \u043f\u0430\u043f\u043a\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u0442\u043e-\u0442\u043e \u0436\u0435 \u0441\u043e\u0432\u0435\u0442\u043e\u0432\u0430\u043b \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043d\u0430 &#171;\u041c\u043e\u043b\u0435\u043a\u0443\u043b\u044b&#187;, &#171;\u041e\u0440\u0433\u0430\u043d\u0438\u0437\u043c\u044b&#187; \u0438 \u0442.\u0434., \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c, \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435, \u043c\u0430\u043b\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0443\u0434\u0435\u043b\u044f\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c, \u0445\u0443\u043a\u0430\u043c, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043b\u043e \u043b\u043e\u0433\u0438\u043a\u0443, \u043d\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u043e \u0442\u043e\u043c, \u0433\u0434\u0435 \u043b\u0443\u0447\u0448\u0435 \u0438 \u043a\u0430\u043a \u043b\u0443\u0447\u0448\u0435 \u0438\u0445 \u0445\u0440\u0430\u043d\u0438\u0442\u044c. <\/p>\n<p>\u041d\u041e, \u0431\u044b\u043b\u0438 \u0438 \u0445\u043e\u0440\u043e\u0448\u0438\u0435, \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044f \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0438\u043b\u0441\u044f. \u0412 \u043d\u0435\u0439 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u0441\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0435 &#171;Core&#187;. \u0421\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e, \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043d\u0430\u0439\u0442\u0438 \u043d\u0435 \u043c\u043e\u0433\u0443, \u043d\u043e \u043a\u0430\u043a \u043d\u0430\u0439\u0434\u0443 &#8212; \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u044e, \u043b\u0438\u0431\u043e \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u044e \u043f\u043e\u0441\u0442 (\u0435\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0442\u043e \u043d\u0430 \u043c\u0435\u0441\u0442\u0435 \u044d\u0442\u043e\u0433\u043e \u0430\u0431\u0437\u0430\u0446\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u0442\u0430\u0442\u044c\u044e), \u043b\u0438\u0431\u043e \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u0432 \u0432\u0438\u0434\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f. <\/p>\n<p>(!) \u041f\u0440\u043e\u0448\u0443 \u0432\u0430\u0441, \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0447\u0442\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u043c\u044b\u0441\u043b\u044c, \u0447\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u0442\u0443\u0442 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e &#8212; \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u043e-\u043b\u0438\u0448\u044c \u043e\u0434\u043d\u0430 \u0438\u0437 \u0438\u0434\u0435\u0439 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441\u0432\u043e\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043c\u043e\u0438 \u0441\u043b\u043e\u0432\u0430, \u043a\u0430\u043a \u0434\u043e\u0433\u043c\u0443 (\u044d\u0442\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u0442\u0435\u043c, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0430\u043b \u0441\u0432\u043e\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 React), \u0432\u0435\u0434\u044c \u044f \u0438 \u0441\u0430\u043c \u043d\u043e\u0432\u0438\u0447\u043e\u043a. <\/p>\n<p>\u0411\u0443\u0434\u0443 \u043e\u0447\u0435\u043d\u044c \u0440\u0430\u0434, \u0435\u0441\u043b\u0438 \u0432\u044b \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044e \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u043a\u0430\u043a \u0438 \u0432\u0430\u0448\u0435\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u043a\u0440\u0438\u0442\u0438\u043a\u0435.<\/p>\n<h3>Components<\/h3>\n<p>\u041d\u0430\u0447\u043d\u0443, \u043f\u043e\u0436\u0430\u043b\u0443\u0439, \u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. <\/p>\n<p>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435, \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0430:<\/p>\n<ul>\n<li>\n<p>\u0423\u043c\u043d\u044b\u0435 (Smart)<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u044b\u0447\u043d\u044b\u0435 (Ordinary)<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0441\u0442\u044b\u0435 (Simple)<\/p>\n<\/li>\n<li>\n<p>UI (UI, \u043a\u0430\u043a \u043d\u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u043e)<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b (Containers)<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u044b (Pages)<\/p>\n<\/li>\n<\/ul>\n<p> \u041f\u0435\u0440\u0432\u044b\u0435 \u0447\u0435\u0442\u044b\u0440\u0435 \u0433\u0440\u0443\u043f\u043f\u044b (Smart, Ordinary, Simple \u0438 UI) \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043f\u0430\u043f\u043a\u0435 Components.  <\/p>\n<p>\u041f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e \u043d\u0438\u0445:<\/p>\n<ul>\n<li>\n<p>UI \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b &#8212; \u044d\u0442\u043e \u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043c\u0435\u043d\u044f\u044e\u0442 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 (\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435) \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043f\u043e \u0442\u0438\u043f\u0443: button, input, textarea, select \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. <\/p>\n<ul>\n<li>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0435 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0438 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c\u0443.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Simple \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b &#8212; \u044d\u0442\u043e \u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438, \u0438\u043d\u0430\u0447\u0435 \u0433\u043e\u0432\u043e\u0440\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435\u0442 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u043b\u043e\u0433\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u044f\u0442.<\/p>\n<ul>\n<li>\n<p>\u041d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0438 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c\u0443.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0445\u0443\u043a\u0438, \u043a\u0440\u043e\u043c\u0435 \u0442\u0435\u0445, \u0447\u0442\u043e \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441 React (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c useState).<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 UI \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Ordinary \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b &#8212; \u044d\u0442\u043e \u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u043b\u043e\u0433\u0438\u043a\u0443, \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0447\u0435\u0433\u043e-\u043b\u0438\u0431\u043e.<\/p>\n<ul>\n<li>\n<p>\u041d\u0435 \u043c\u043e\u0433\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u043a\u0430\u043a \u0438 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c\u0443.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0445\u0443\u043a\u0438, \u043a\u0440\u043e\u043c\u0435 \u0442\u0435\u0445, \u0447\u0442\u043e \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441 React (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c useState).<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Simple \u0438 UI \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Smart \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b &#8212; \u044d\u0442\u043e \u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443, \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0447\u0435\u0433\u043e-\u043b\u0438\u0431\u043e<\/p>\n<ul>\n<li>\n<p>\u041c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u043a\u0430\u043a \u0438 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c\u0443 (\u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u044f \u0435\u0433\u043e)<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0445\u0443\u043a\u0438, \u043a\u0440\u043e\u043c\u0435 \u0442\u0435\u0445, \u0447\u0442\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0441 \u0441\u0435\u0442\u044c\u044e<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Ordinary, Simple \u0438 UI \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0430\u043f\u043a\u0438 Componets:<\/p>\n<pre><code>. \u2514\u2500\u2500 src\/     \u251c\u2500\u2500 components\/     \u2502   \u251c\u2500\u2500 ordinary     \u2502   \u251c\u2500\u2500 simple     \u2502   \u251c\u2500\u2500 smart     \u2502   \u2514\u2500\u2500 ui     \u2514\u2500\u2500 ...<\/code><\/pre>\n<p>\u041e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0434\u0432\u0435 \u0433\u0440\u0443\u043f\u043f\u044b (Containers \u0438 Pages) \u0438\u043c\u0435\u044e\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u043f\u043a\u0438 \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043f\u0430\u043f\u043a\u0430 src).<\/p>\n<ul>\n<li>\n<p>Containers &#8212; \u044d\u0442\u043e \u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0442 \u043d\u0435\u043a\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446, \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u043a \u0442\u043e\u043c\u0443 \u0436\u0435, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0447\u0435\u0442\u044b\u0440\u0435\u0445 \u0433\u0440\u0443\u043f\u043f \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c, \u043a\u0430\u043a\u0438\u043c-\u043b\u0438\u0431\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438 \u0438\u043b\u0438 \u0441\u0435\u0442\u044c\u044e, \u0435\u0441\u043b\u0438 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e\u0431\u043e\u0431\u0449\u0435\u043d\u043d\u043e.<\/p>\n<\/li>\n<li>\n<p>Pages &#8212; \u044d\u0442\u043e \u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c \u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u0438\u0437 \u043f\u0430\u043f\u043a\u0438 Components, \u0435\u0441\u043b\u0438 \u0432 \u044d\u0442\u043e\u043c \u0435\u0441\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c. \u041c\u043e\u0433\u0443\u0442, \u043a\u0430\u043a \u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b, \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u043f\u0430\u043f\u043a\u0438:<\/p>\n<pre><code>. \u2514\u2500\u2500 src\/     \u251c\u2500\u2500 components\/     \u2502   \u251c\u2500\u2500 ordinary     \u2502   \u251c\u2500\u2500 simple     \u2502   \u251c\u2500\u2500 smart     \u2502   \u2514\u2500\u2500 ui     \u251c\u2500\u2500 containers     \u251c\u2500\u2500 pages     \u2514\u2500\u2500 ...<\/code><\/pre>\n<p>\u0421\u0430\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u043f\u043a\u0438, \u0435\u0441\u0442\u044c 2 (\u044d\u0442\u043e \u0447\u0438\u0441\u043b\u043e \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043e\u0439) \u0444\u0430\u0439\u043b\u0430:<\/p>\n<ul>\n<li>\n<p>index.tsx  &#8212; \u0444\u0430\u0439\u043b, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u0430\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442<\/p>\n<\/li>\n<li>\n<p>styled.ts &#8212; \u0444\u0430\u0439\u043b, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0441\u0442\u0438\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b (\u0435\u0433\u043e \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430 styles.s\u0441ss, \u043b\u0438\u0431\u043e \u0436\u0435 styles.css, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u0447\u0435\u043c \u0432\u044b \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435\u0441\u044c \u0434\u043b\u044f \u0441\u0442\u0438\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0432\u043e\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432)<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 Align. \u0425\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u043f\u043e\u0434 \u0433\u0440\u0443\u043f\u043f\u0443 &#171;Simple&#187;, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0433\u043b\u0443\u043f\u044b\u043c (\u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043d\u0443\u0436\u0434\u044b \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435) \u0438 \u043d\u0435 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439, \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0439, UI \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442.<\/p>\n<pre><code class=\"javascript\">\/\/ index.tsx  import React, { memo } from \"react\"; import * as S from \".\/styled\"; \/\/ \u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0438\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b  const Align = memo(({ children, axis, isAdaptable = false }: Readonly&lt;Props&gt;) =&gt; { \treturn ( \t\t&lt;S.Align $axis={axis} $isAdaptable={isAdaptable}&gt; \t\t\t{children} \t\t&lt;\/S.Align&gt; \t); });  export { Align }; export interface Props { \taxis: S.Axis; \tchildren?: React.ReactNode; \tisAdaptable?: boolean; }<\/code><\/pre>\n<pre><code class=\"javascript\">\/\/ styled.ts  import styled, { css } from \"styled-components\";  const notAdaptableMixin = css` \twidth: 100%; \theight: 100%; \tmax-height: 100%; \tmax-width: 100%; `;  const adaptableMixin = css&lt;AlignProps&gt;` \twidth: ${(props) =&gt; !props.$axis.includes(\"x\") &amp;&amp; \"100%\"}; \theight: ${(props) =&gt; !props.$axis.includes(\"y\") &amp;&amp; \"100%\"}; \tmin-width: ${(props) =&gt; props.$axis.includes(\"x\") &amp;&amp; \"100%\"}; \tmin-height: ${(props) =&gt; props.$axis.includes(\"y\") &amp;&amp; \"100%\"}; `;  export const Align = styled.div&lt;AlignProps&gt;` \tdisplay: flex; \tflex-grow: 1; \tjustify-content: ${(props) =&gt; (props.$axis.includes(\"x\") ? \"center\" : \"start\")}; \talign-items: ${(props) =&gt; (props.$axis.includes(\"y\") ? \"center\" : \"start\")}; \t${(props) =&gt; (props.$isAdaptable ? adaptableMixin : notAdaptableMixin)}; `;  export interface AlignProps { \t$axis: Axis; \t$isAdaptable?: boolean; }  export type Axis = (\"y\" | \"x\")[] | \"x\" | \"y\"; <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0441\u0430\u043c\u043e\u043c \u0441\u043b\u0430\u0434\u043a\u043e\u043c&#8230;<\/p>\n<h3>Core<\/h3>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u043f\u0430\u043f\u043a\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;\u044f\u0434\u0440\u043e\u043c&#187; \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412 \u043d\u0435\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432\u0441\u0435, \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c, \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u0442\u0435\u043c\u0430 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0442.\u0434.<\/p>\n<p>\u042d\u0442\u0430 \u043f\u0430\u043f\u043a\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442:<\/p>\n<ul>\n<li>\n<p>Config &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043d\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0431\u044d\u043a\u0435\u043d\u0434\u043e\u043c)<\/p>\n<\/li>\n<li>\n<p>Constants &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0430\u0445 \u0438 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f\u0445)<\/p>\n<\/li>\n<li>\n<p>Hooks &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u0445\u0443\u043a\u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u0445\u0443\u043a\u0438 (\u0445\u0443\u043a\u0438, \u0447\u0442\u043e \u0431\u044b\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u0432\u0430\u043c\u0438).<\/p>\n<\/li>\n<li>\n<p>Models &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043c\u043e\u0434\u0435\u043b\u0438, \u0447\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0441 \u0431\u044d\u043a\u0435\u043d\u0434\u0430.<\/p>\n<\/li>\n<li>\n<p>Schemes &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0441\u0445\u0435\u043c\u044b \u0444\u043e\u0440\u043c, \u0442\u0430\u0431\u043b\u0438\u0446 \u0438 \u0442.\u0434.<\/p>\n<\/li>\n<li>\n<p>Services &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0441\u0430\u043c\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u044b, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0431\u044d\u043a\u0435\u043d\u0434\u043e\u043c.<\/p>\n<\/li>\n<li>\n<p>Store &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0441\u0445\u0435\u043c\u044b \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 (\u0435\u0441\u043b\u0438 \u0412\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 MobX), \u0435\u0441\u043b\u0438 \u0436\u0435 \u0432\u044b \u043e\u0442\u0434\u0430\u0435\u0442\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0435 Redux, \u0442\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u043c\u043e\u0433\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u044d\u043a\u0448\u0435\u043d\u044b, \u0440\u0435\u0434\u044c\u044e\u0441\u0435\u0440\u044b \u0438 \u0442.\u0434.<\/p>\n<\/li>\n<li>\n<p>Theme (\u0434\u043b\u044f Styled-Components) &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0442\u0435\u043c\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>Types &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0434\u0443\u043b\u0435\u0439.<\/p>\n<\/li>\n<li>\n<p>Utils &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435, \u043f\u0440\u043e\u0441\u0442\u044b\u0435, \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0445\u0443\u043a\u0430\u0445, \u043b\u0438\u0431\u043e \u0436\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u0445.<\/p>\n<\/li>\n<li>\n<p>api.ts &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 HTTP \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 axios), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u0443\u0442\u0438\u0440\u0443\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b (\u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043a\u0430\u043a\u0438\u0445-\u043b\u0438\u0431\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440).<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043f\u0430\u043f\u043e\u043a<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">\/\/ config\/api.config.ts  export const serverURI = \"http:\/\/localhost:8080\"; export const routesPrefix = '\/api\/v1';   \/\/ config\/routes.config.ts  import { routesPrefix } from \".\/api.config\";  export const productBrowserRoutes = { \tgetOne: (to: string = \":code\") =&gt; `\/product\/${to}`, \tsearch: (param: string = \":search\") =&gt; `\/search\/${param}`, };  export const productAPIRoutes = { \tgetOne: (code: string) =&gt; `${routesPrefix}\/product\/code\/${code}`, \tsearch: () =&gt; `${routesPrefix}\/product\/search`, };<\/code><\/pre>\n<p>\u0414\u043e\u0432\u043e\u043b\u044c\u043d\u043e-\u0442\u0430\u043a\u0438 \u0443\u0434\u043e\u0431\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0440\u043e\u0443\u0442\u044b \u0432 \u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435. \u0415\u0441\u043b\u0438 \u0432\u0434\u0440\u0443\u0433 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0431\u044d\u043a\u0435\u043d\u0434\u0430 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u0441\u044f \u0440\u043e\u0443\u0442\u044b, \u0442\u043e \u0438\u0445 \u043b\u0435\u0433\u043a\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0432 \u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u043d\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0441\u044c, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c, \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443. <\/p>\n<pre><code class=\"javascript\">\/\/ constants\/message.constants.ts  export const UNKNOWN_ERROR = \"\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430\";<\/code><\/pre>\n<pre><code class=\"javascript\">\/\/ hooks\/useAPI.ts \/\/ \u0425\u0443\u043a \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438 \/* eslint-disable react-hooks\/exhaustive-deps *\/  import { useCallback, useEffect } from \"react\"; import { useLocalObservable } from \"mobx-react-lite\"; import type { API, Schema, Take } from \"@core\/types\";  function useAPI&lt; \tF extends API.Service.Function&lt;API.Response&lt;any&gt;&gt;, \tR extends Take.FromServiceFunction.Response&lt;F&gt;, \tP extends Parameters&lt;F&gt; &gt;(service: F, { isPendingAfterMount = false, isIgnoreHTTPErrors = false }: Options = {}) { \tconst localStore = useLocalObservable&lt;Store&gt;(() =&gt; ({ \t\tisPending: { \t\t\tvalue: isPendingAfterMount, \t\t\tset: function (value) { \t\t\t\tthis.value = value; \t\t\t}, \t\t}, \t}));  \tconst call = useCallback( \t\tasync (...params: P): Promise&lt;R[\"result\"]&gt; =&gt; { \t\t\tlocalStore.isPending.set(true);  \t\t\ttry { \t\t\t\tconst { data } = await service(...params); \t\t\t\tconst { result } = data;  \t\t\t\tlocalStore.isPending.set(false);  \t\t\t\treturn result; \t\t\t} catch (error) { \t\t\t\tif (isIgnoreHTTPErrors === false) { \t\t\t\t\tconsole.error(error); \t\t\t\t}  \t\t\t\tlocalStore.isPending.set(false);  \t\t\t\tthrow error; \t\t\t} \t\t}, \t\t[service, isIgnoreHTTPErrors] \t);  \tconst isPending = useCallback(() =&gt; { \t\treturn localStore.isPending.value; \t}, []);  \tuseEffect(() =&gt; { \t\tlocalStore.isPending.set(isPendingAfterMount); \t}, [isPendingAfterMount]);  \treturn { \t\tcall, \t\tisPending, \t}; }  export { useAPI }; export interface Options { \tisPendingAfterMount?: boolean; \tisIgnoreHTTPErrors?: boolean; }  type Store = Schema.Store&lt;{ isPending: boolean }&gt;;<\/code><\/pre>\n<pre><code class=\"javascript\">\/\/ models\/product.model.ts \/\/ \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0442\u043e\u0432\u0430\u0440\u0430  export interface ProductModel { \tid: number; \tname: string; \tcode: string; \tinfo: { \t\tdescription: string; \t\tnote: string; \t}; \tconfig: { \t\tisAllowedForPurchaseIfInStockZero: boolean; \t\tisInStock: boolean; \t}; \tseo: { \t\ttitle: string; \t\tkeywords: string; \t\tdescription: string; \t}; }<\/code><\/pre>\n<pre><code class=\"javascript\">\/\/ services\/product.service.ts \/\/ \u0421\u0435\u0440\u0432\u0438\u0441\u044b \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0442\u043e\u0432\u0430\u0440\u0430\u043c\u0438  import { api } from \"..\/api\"; import { routesConfig } from \"..\/config\"; import type { ProductModel } from \"..\/models\"; import type { API } from \"..\/types\";  export function getOne(code: string) { \treturn api.get&lt;API.Service.Response.GetOne&lt;ProductModel&gt;&gt;( \t\troutesConfig.productAPIRoutes.getOne(code) \t); }<\/code><\/pre>\n<pre><code class=\"javascript\">\/\/ theme\/index.ts \/\/ \u0422\u0435\u043c\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f  import { DefaultTheme } from \"styled-components\";  export const theme: DefaultTheme = { \tcolors: { \t\t\tprimary: \"#2648f1\", \t\t\tintense: \"#151e27\", \t\t\tgreen: \"#53d769\", \t\t\tgrey: \"#626b73\", \t\t\tred: \"#f73d34\", \t\t\torange: \"#fdb549\", \t\t\tyellow: \"#ffe243\", \t\t\twhite: \"white\", \t\t}, };<\/code><\/pre>\n<pre><code class=\"javascript\">\/\/ types\/index.tsx \/\/ \u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b  import type { AxiosResponse } from \"axios\";  export namespace API { \texport namespace Service { \t\texport namespace Response { \t\t\texport type Upsert&lt;T&gt; = Response&lt;T | null&gt;; \t\t\texport type GetOne&lt;T&gt; = Response&lt;T | null&gt;; \t\t\texport type GetMany&lt;T&gt; = Response&lt;{ \t\t\t\trows: T[]; \t\t\t\ttotalRowCount: number; \t\t\t\ttotalPageCount: number; \t\t\t}&gt;; \t\t} \t\texport type Function&lt;T extends API.Response&lt;any&gt;, U extends any[] = any[]&gt; = ( \t\t\t...params: U \t\t) =&gt; Promise&lt;AxiosResponse&lt;T&gt;&gt;; \t} \texport type Response&lt;T&gt; = { \t\tstatus: number; \t\tresult: T; \t}; }<\/code><\/pre>\n<pre><code class=\"javascript\">\/\/ utils\/throttle.ts  function throttle&lt;P extends any[]&gt;(func: (...params: P) =&gt; any, limit: number) { \tlet inThrottle: boolean;  \treturn function (...params: P): any { \t\tif (!inThrottle) { \t\t\tinThrottle = true; \t\t\tfunc(...params); \t\t\tsetTimeout(() =&gt; (inThrottle = false), limit); \t\t} \t}; }  export { throttle };<\/code><\/pre>\n<pre><code class=\"javascript\">\/\/ store\/index.tsx  import { createContext } from \"react\"; import { useLocalObservable } from \"mobx-react-lite\";  import { app, App } from \".\/segments\/app\"; import { layout, Layout } from \".\/segments\/layout\"; import { counters, Counters } from \".\/segments\/counters\";  export const combinedStore = { layout, app, counters }; export const storeContext = createContext&lt;StoreContext&gt;(combinedStore); export function StoreProvider({ children }: { children: React.ReactNode }) { \tconst store = useLocalObservable(() =&gt; combinedStore);  \treturn &lt;storeContext.Provider value={store}&gt;{children}&lt;\/storeContext.Provider&gt;; }  export type StoreContext = { \tapp: App; \tlayout: Layout; \tcounters: Counters; };<\/code><\/pre>\n<pre><code class=\"javascript\">\/\/ api.ts \/\/ \u042d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 AXIOS \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c  import axios from \"axios\"; import { apiConfig } from \".\/config\";  const api = axios.create({ \tbaseURL: apiConfig.serverURI, });  api.interceptors.request.use((req) =&gt; { \treturn { \t\t...req, \t\tbaseURL: apiConfig.serverURI, \t}; });  export { api };<\/code><\/pre>\n<p>\u0423\u0445 \u0442\u044b! \u041a\u0430\u043a \u0436\u0435 \u043c\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c.<\/p>\n<\/div>\n<\/details>\n<h2>\u0418 \u043d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a&#8230;<\/h2>\n<p>\u0415\u0441\u0442\u044c \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e, \u043d\u0435\u043c\u0430\u043b\u043e\u0432\u0430\u0436\u043d\u044b\u0445 \u043f\u0430\u043f\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0430\u043a\u0436\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>Assets &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a: \u0438\u043a\u043e\u043d\u043a\u0438, \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0448\u0440\u0438\u0444\u0442\u044b \u0438 \u0442.\u0434. (\u0438\u0445, \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u0442\u0430\u043a\u0436\u0435 \u0441\u0442\u043e\u0438\u0442 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u0430 \u043f\u0430\u043f\u043a\u0438)<\/p>\n<\/li>\n<li>\n<p>Routes &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 (\u043b\u0438\u0431\u043e \u0436\u0435 \u0444\u0430\u0439\u043b\u0435, \u043a\u043e\u043c\u0443 \u043a\u0430\u043a \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f) \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u0440\u043e\u0443\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043f\u0440\u0438\u043c\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043d\u0438\u0436\u0435).<\/p>\n<\/li>\n<li>\n<p>Styles &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0438\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043a\u043e \u0432\u0441\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0443, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"javascript\">\/\/ routes\/index.tsx  import { Switch, Route } from \"react-router-dom\";  \/\/ \u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b import { Product } from \"..\/pages\/Product\"; ... import { NotFound } from \"..\/pages\/NotFound\";  import { routesConfig } from \"..\/core\/config\";  const Routes = () =&gt; { \treturn ( \t\t&lt;Switch&gt; \t\t\t&lt;Route exact path={routesConfig.productBrowserRoutes.getOne()}&gt; \t\t\t\t&lt;Product \/&gt; \t\t\t&lt;\/Route&gt; \t\t\t{\/* \u041e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043a\u0430\u043a-\u0442\u043e \u0440\u043e\u0443\u0442\u044b *\/} \t\t\t&lt;Route&gt; \t\t\t\t&lt;NotFound \/&gt; \t\t\t&lt;\/Route&gt; \t\t&lt;\/Switch&gt; \t); };  export { Routes }; <\/code><\/pre>\n<p>\u041e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0435\u0449\u0435 2 \u0444\u0430\u0439\u043b\u0430:<\/p>\n<ul>\n<li>\n<p>app.tsx &#8212; \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c:<\/p>\n<pre><code class=\"javascript\">\/\/ app.tsx  import React, { useEffect } from \"react\";  \/\/ \u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0440\u043e\u0443\u0442\u044b import { Routes } from \".\/routes\";  const App = () =&gt; { \treturn ( \t\t\t&lt;Routes \/&gt; \t); };  export { App }; <\/code><\/pre>\n<ul>\n<li>\n<p>index.tsx &#8212; \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0444\u0430\u0439\u043b \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u043d \u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"javascript\">import React from \"react\"; import ReactDOM from \"react-dom\"; import { BrowserRouter } from \"react-router-dom\"; import { ThemeProvider } from \"styled-components\";  \/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0448\u0435 import { App } from \".\/app\"; \/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0438\u043b\u0438 import { BodyStyles } from \".\/styles\";  import { StoreProvider } from \"..\/core\/store\"; \/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0442\u0435\u043c\u0443 import { theme } from \"..\/core\/theme\";  import reportWebVitals from \".\/reportWebVitals\";  const app = document.getElementById(\"app\");  ReactDOM.render( \t&lt;React.StrictMode&gt; \t\t&lt;ThemeProvider theme={theme}&gt; \t\t\t&lt;BodyStyles \/&gt; \t\t\t&lt;BrowserRouter&gt; \t\t\t\t&lt;StoreProvider&gt; \t\t\t\t\t&lt;App \/&gt; \t\t\t\t&lt;\/StoreProvider&gt; \t\t\t&lt;\/BrowserRouter&gt; \t\t&lt;\/ThemeProvider&gt; \t&lt;\/React.StrictMode&gt;, \tapp );  reportWebVitals(); <\/code><\/pre>\n<p>\u0418 \u043d\u0430 \u044d\u0442\u043e\u043c, \u044f \u0434\u0443\u043c\u0430\u044e, \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c.<\/p>\n<p>\u0418\u0442\u043e\u0433\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>. \u2514\u2500\u2500 src\/     \u251c\u2500\u2500 assets\/     \u2502   \u251c\u2500\u2500 fonts     \u2502   \u2514\u2500\u2500 icons     \u251c\u2500\u2500 components\/     \u2502   \u251c\u2500\u2500 ordinary     \u2502   \u251c\u2500\u2500 simple     \u2502   \u251c\u2500\u2500 smart     \u2502   \u2514\u2500\u2500 ui     \u251c\u2500\u2500 containers     \u251c\u2500\u2500 core\/     \u2502   \u251c\u2500\u2500 config     \u2502   \u251c\u2500\u2500 constants     \u2502   \u251c\u2500\u2500 hooks     \u2502   \u251c\u2500\u2500 models     \u2502   \u251c\u2500\u2500 schemes     \u2502   \u251c\u2500\u2500 services     \u2502   \u251c\u2500\u2500 store     \u2502   \u251c\u2500\u2500 theme     \u2502   \u251c\u2500\u2500 types     \u2502   \u251c\u2500\u2500 utils     \u2502   \u2514\u2500\u2500 api.ts     \u251c\u2500\u2500 pages     \u251c\u2500\u2500 routes     \u251c\u2500\u2500 styles     \u251c\u2500\u2500 app.tsx     \u2514\u2500\u2500 index.tsx<\/code><\/pre>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0430\u0441\u044c \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0438 \u0432\u044b \u0443\u0437\u043d\u0430\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u0434\u043b\u044f \u0441\u0435\u0431\u044f, \u0442\u043e \u044f \u043e\u0447\u0435\u043d\u044c \u044d\u0442\u043e\u043c\u0443 \u0440\u0430\u0434.<\/p>\n<p><a href=\"https:\/\/github.com\/gduke3\/react-rest-api-typescript-boilerplate\" rel=\"noopener noreferrer nofollow\">\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/a> (\u0437\u0430 \u0442\u0430\u043a\u043e\u0439 \u0441\u043a\u0443\u0434\u043d\u044b\u0439 \u0440\u0438\u0434\u043c\u0438, \u043c\u043d\u0435 \u0435\u0449\u0435 \u043d\u0435 \u043f\u043e \u0441\u0438\u043b\u0430\u043c \u0440\u0430\u0437\u0433\u043e\u0432\u043e\u0440\u043d\u044b\u0439 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0439).<\/p>\n<p>\u0412\u0441\u0435\u043c \u0443\u0434\u0430\u0447\u0438 \u0438 \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u0435 \u0441\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435.<\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/546162\/\"> https:\/\/habr.com\/ru\/post\/546162\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0414\u043e\u0431\u0440\u043e\u0433\u043e %\u0432\u0440\u0435\u043c\u044f_\u0441\u0443\u0442\u043e\u043a, \u0445\u0430\u0431\u0440\u043e\u0432\u0447\u0430\u043d\u0435!<\/p>\n<p>\u041a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u0441\u0442\u0430\u0442\u044c\u0438 \u044f \u0435\u0449\u0435 \u043d\u0435 \u043f\u0438\u0441\u0430\u043b, \u043e\u043f\u044b\u0442\u0430 \u0432 \u044d\u0442\u043e\u043c \u043d\u0435\u0442 \u043e\u0442 \u0441\u043b\u043e\u0432\u0430 \u0441\u043e\u0432\u0441\u0435\u043c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043d\u0435 \u0441\u0443\u0434\u0438\u0442\u0435 \u0441\u0442\u0440\u043e\u0433\u043e \u0438 \u043f\u0440\u043e\u0448\u0443 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f, \u0435\u0441\u043b\u0438 \u0433\u0434\u0435-\u0442\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0443 \u043e\u0448\u0438\u0431\u043a\u0438. <\/p>\n<p>\u042d\u0442\u043e \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u043e\u0432\u044b\u0439 \u043e\u043f\u044b\u0442, \u043c\u043d\u0435 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u0435\u0449\u0435 \u043d\u0435 \u0434\u043e\u0432\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u0438 \u043d\u0430\u0440\u0430\u0431\u043e\u0442\u043a\u0430\u043c\u0438 \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e\u043c.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<h2>\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435<\/h2>\n<p>\u041a\u043e\u0433\u0434\u0430 \u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0430\u043b \u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 React, \u043c\u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0438\u0441\u043a\u0430\u0442\u044c, \u0438 \u0438\u0441\u043a\u0430\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e-\u0442\u0430\u043a\u0438 \u0434\u043e\u043b\u0433\u043e, \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043c\u043e\u0433\u043b\u0430 \u0431\u044b \u043c\u043d\u0435 \u0433\u0440\u0430\u043c\u043e\u0442\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043c\u043e\u0438\u0445 \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432, \u043d\u043e \u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0431\u044b\u043b\u043e \u043c\u0430\u043b\u043e.<\/p>\n<p>\u041a\u0442\u043e-\u0442\u043e \u0441\u043e\u0432\u0435\u0442\u043e\u0432\u0430\u043b \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043b\u043e\u0441\u043a\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u0434\u043b\u044f \u043f\u0430\u043f\u043a\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u0442\u043e-\u0442\u043e \u0436\u0435 \u0441\u043e\u0432\u0435\u0442\u043e\u0432\u0430\u043b \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043d\u0430 &#171;\u041c\u043e\u043b\u0435\u043a\u0443\u043b\u044b&#187;, &#171;\u041e\u0440\u0433\u0430\u043d\u0438\u0437\u043c\u044b&#187; \u0438 \u0442.\u0434., \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c, \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435, \u043c\u0430\u043b\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0443\u0434\u0435\u043b\u044f\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c, \u0445\u0443\u043a\u0430\u043c, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043b\u043e \u043b\u043e\u0433\u0438\u043a\u0443, \u043d\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u043e \u0442\u043e\u043c, \u0433\u0434\u0435 \u043b\u0443\u0447\u0448\u0435 \u0438 \u043a\u0430\u043a \u043b\u0443\u0447\u0448\u0435 \u0438\u0445 \u0445\u0440\u0430\u043d\u0438\u0442\u044c. <\/p>\n<p>\u041d\u041e, \u0431\u044b\u043b\u0438 \u0438 \u0445\u043e\u0440\u043e\u0448\u0438\u0435, \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044f \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0438\u043b\u0441\u044f. \u0412 \u043d\u0435\u0439 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u0441\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0435 &#171;Core&#187;. \u0421\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e, \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043d\u0430\u0439\u0442\u0438 \u043d\u0435 \u043c\u043e\u0433\u0443, \u043d\u043e \u043a\u0430\u043a \u043d\u0430\u0439\u0434\u0443 &#8212; \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u044e, \u043b\u0438\u0431\u043e \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u044e \u043f\u043e\u0441\u0442 (\u0435\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0442\u043e \u043d\u0430 \u043c\u0435\u0441\u0442\u0435 \u044d\u0442\u043e\u0433\u043e \u0430\u0431\u0437\u0430\u0446\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u0442\u0430\u0442\u044c\u044e), \u043b\u0438\u0431\u043e \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u0432 \u0432\u0438\u0434\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f. <\/p>\n<p>(!) \u041f\u0440\u043e\u0448\u0443 \u0432\u0430\u0441, \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0447\u0442\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u043c\u044b\u0441\u043b\u044c, \u0447\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u0442\u0443\u0442 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e &#8212; \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u043e-\u043b\u0438\u0448\u044c \u043e\u0434\u043d\u0430 \u0438\u0437 \u0438\u0434\u0435\u0439 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441\u0432\u043e\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043c\u043e\u0438 \u0441\u043b\u043e\u0432\u0430, \u043a\u0430\u043a \u0434\u043e\u0433\u043c\u0443 (\u044d\u0442\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u0442\u0435\u043c, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0430\u043b \u0441\u0432\u043e\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 React), \u0432\u0435\u0434\u044c \u044f \u0438 \u0441\u0430\u043c \u043d\u043e\u0432\u0438\u0447\u043e\u043a. <\/p>\n<p>\u0411\u0443\u0434\u0443 \u043e\u0447\u0435\u043d\u044c \u0440\u0430\u0434, \u0435\u0441\u043b\u0438 \u0432\u044b \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044e \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u043a\u0430\u043a \u0438 \u0432\u0430\u0448\u0435\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u043a\u0440\u0438\u0442\u0438\u043a\u0435.<\/p>\n<h3>Components<\/h3>\n<p>\u041d\u0430\u0447\u043d\u0443, \u043f\u043e\u0436\u0430\u043b\u0443\u0439, \u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. <\/p>\n<p>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435, \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0430:<\/p>\n<ul>\n<li>\n<p>\u0423\u043c\u043d\u044b\u0435 (Smart)<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u044b\u0447\u043d\u044b\u0435 (Ordinary)<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0441\u0442\u044b\u0435 (Simple)<\/p>\n<\/li>\n<li>\n<p>UI (UI, \u043a\u0430\u043a \u043d\u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u043e)<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b (Containers)<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u044b (Pages)<\/p>\n<\/li>\n<\/ul>\n<p> \u041f\u0435\u0440\u0432\u044b\u0435 \u0447\u0435\u0442\u044b\u0440\u0435 \u0433\u0440\u0443\u043f\u043f\u044b (Smart, Ordinary, Simple \u0438 UI) \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043f\u0430\u043f\u043a\u0435 Components.  <\/p>\n<p>\u041f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e \u043d\u0438\u0445:<\/p>\n<ul>\n<li>\n<p>UI \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b &#8212; \u044d\u0442\u043e \u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043c\u0435\u043d\u044f\u044e\u0442 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 (\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435) \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043f\u043e \u0442\u0438\u043f\u0443: button, input, textarea, select \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. <\/p>\n<ul>\n<li>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0435 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0438 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c\u0443.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Simple \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b &#8212; \u044d\u0442\u043e \u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438, \u0438\u043d\u0430\u0447\u0435 \u0433\u043e\u0432\u043e\u0440\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435\u0442 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u043b\u043e\u0433\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u044f\u0442.<\/p>\n<ul>\n<li>\n<p>\u041d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0438 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c\u0443.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0445\u0443\u043a\u0438, \u043a\u0440\u043e\u043c\u0435 \u0442\u0435\u0445, \u0447\u0442\u043e \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441 React (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c useState).<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 UI \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Ordinary \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b &#8212; \u044d\u0442\u043e \u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u043b\u043e\u0433\u0438\u043a\u0443, \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0447\u0435\u0433\u043e-\u043b\u0438\u0431\u043e.<\/p>\n<ul>\n<li>\n<p>\u041d\u0435 \u043c\u043e\u0433\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u043a\u0430\u043a \u0438 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c\u0443.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0445\u0443\u043a\u0438, \u043a\u0440\u043e\u043c\u0435 \u0442\u0435\u0445, \u0447\u0442\u043e \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441 React (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c useState).<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Simple \u0438 UI \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Smart \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b &#8212; \u044d\u0442\u043e \u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443, \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0447\u0435\u0433\u043e-\u043b\u0438\u0431\u043e<\/p>\n<ul>\n<li>\n<p>\u041c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u043a\u0430\u043a \u0438 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c\u0443 (\u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u044f \u0435\u0433\u043e)<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0445\u0443\u043a\u0438, \u043a\u0440\u043e\u043c\u0435 \u0442\u0435\u0445, \u0447\u0442\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0441 \u0441\u0435\u0442\u044c\u044e<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Ordinary, Simple \u0438 UI \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0430\u043f\u043a\u0438 Componets:<\/p>\n<pre><code>. \u2514\u2500\u2500 src\/     \u251c\u2500\u2500 components\/     \u2502   \u251c\u2500\u2500 ordinary     \u2502   \u251c\u2500\u2500 simple     \u2502   \u251c\u2500\u2500 smart     \u2502   \u2514\u2500\u2500 ui     \u2514\u2500\u2500 ...<\/code><\/pre>\n<p>\u041e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0434\u0432\u0435 \u0433\u0440\u0443\u043f\u043f\u044b (Containers \u0438 Pages) \u0438\u043c\u0435\u044e\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u043f\u043a\u0438 \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043f\u0430\u043f\u043a\u0430 src).<\/p>\n<ul>\n<li>\n<p>Containers &#8212; \u044d\u0442\u043e \u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0442 \u043d\u0435\u043a\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446, \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u043a \u0442\u043e\u043c\u0443 \u0436\u0435, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0447\u0435\u0442\u044b\u0440\u0435\u0445 \u0433\u0440\u0443\u043f\u043f \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c, \u043a\u0430\u043a\u0438\u043c-\u043b\u0438\u0431\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438 \u0438\u043b\u0438 \u0441\u0435\u0442\u044c\u044e, \u0435\u0441\u043b\u0438 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e\u0431\u043e\u0431\u0449\u0435\u043d\u043d\u043e.<\/p>\n<\/li>\n<li>\n<p>Pages &#8212; \u044d\u0442\u043e \u0442\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c \u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u0438\u0437 \u043f\u0430\u043f\u043a\u0438 Components, \u0435\u0441\u043b\u0438 \u0432 \u044d\u0442\u043e\u043c \u0435\u0441\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c. \u041c\u043e\u0433\u0443\u0442, \u043a\u0430\u043a \u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b, \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u043f\u0430\u043f\u043a\u0438:<\/p>\n<pre><code>. \u2514\u2500\u2500 src\/     \u251c\u2500\u2500 components\/     \u2502   \u251c\u2500\u2500 ordinary     \u2502   \u251c\u2500\u2500 simple     \u2502   \u251c\u2500\u2500 smart     \u2502   \u2514\u2500\u2500 ui     \u251c\u2500\u2500 containers     \u251c\u2500\u2500 pages     \u2514\u2500\u2500 ...<\/code><\/pre>\n<p>\u0421\u0430\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u043f\u043a\u0438, \u0435\u0441\u0442\u044c 2 (\u044d\u0442\u043e \u0447\u0438\u0441\u043b\u043e \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043e\u0439) \u0444\u0430\u0439\u043b\u0430:<\/p>\n<ul>\n<li>\n<p>index.tsx  &#8212; \u0444\u0430\u0439\u043b, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u0430\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442<\/p>\n<\/li>\n<li>\n<p>styled.ts &#8212; \u0444\u0430\u0439\u043b, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0441\u0442\u0438\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b (\u0435\u0433\u043e \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430 styles.s\u0441ss, \u043b\u0438\u0431\u043e \u0436\u0435 styles.css, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u0447\u0435\u043c \u0432\u044b \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435\u0441\u044c \u0434\u043b\u044f \u0441\u0442\u0438\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0432\u043e\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432)<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 Align. \u0425\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u043f\u043e\u0434 \u0433\u0440\u0443\u043f\u043f\u0443 &#171;Simple&#187;, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0433\u043b\u0443\u043f\u044b\u043c (\u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043d\u0443\u0436\u0434\u044b \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435) \u0438 \u043d\u0435 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439, \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0439, UI \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442.<\/p>\n<pre><code class=\"javascript\">\/\/ index.tsx  import React, { memo } from \"react\"; import * as S from \".\/styled\"; \/\/ \u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0438\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b  const Align = memo(({ children, axis, isAdaptable = false }: Readonly&lt;Props&gt;) =&gt; { \treturn ( \t\t&lt;S.Align $axis={axis} $isAdaptable={isAdaptable}&gt; \t\t\t{children} \t\t&lt;\/S.Align&gt; \t); });  export { Align }; export interface Props { \taxis: S.Axis; \tchildren?: React.ReactNode; \tisAdaptable?: boolean; }<\/code><\/pre>\n<pre><code class=\"javascript\">\/\/ styled.ts  import styled, { css } from \"styled-components\";  const notAdaptableMixin = css` \twidth: 100%; \theight: 100%; \tmax-height: 100%; \tmax-width: 100%; `;  const adaptableMixin = css&lt;AlignProps&gt;` \twidth: ${(props) =&gt; !props.$axis.includes(\"x\") &amp;&amp; \"100%\"}; \theight: ${(props) =&gt; !props.$axis.includes(\"y\") &amp;&amp; \"100%\"}; \tmin-width: ${(props) =&gt; props.$axis.includes(\"x\") &amp;&amp; \"100%\"}; \tmin-height: ${(props) =&gt; props.$axis.includes(\"y\") &amp;&amp; \"100%\"}; `;  export const Align = styled.div&lt;AlignProps&gt;` \tdisplay: flex; \tflex-grow: 1; \tjustify-content: ${(props) =&gt; (props.$axis.includes(\"x\") ? \"center\" : \"start\")}; \talign-items: ${(props) =&gt; (props.$axis.includes(\"y\") ? \"center\" : \"start\")}; \t${(props) =&gt; (props.$isAdaptable ? adaptableMixin : notAdaptableMixin)}; `;  export interface AlignProps { \t$axis: Axis; \t$isAdaptable?: boolean; }  export type Axis = (\"y\" | \"x\")[] | \"x\" | \"y\"; <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0441\u0430\u043c\u043e\u043c \u0441\u043b\u0430\u0434\u043a\u043e\u043c&#8230;<\/p>\n<h3>Core<\/h3>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u043f\u0430\u043f\u043a\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;\u044f\u0434\u0440\u043e\u043c&#187; \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412 \u043d\u0435\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432\u0441\u0435, \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c, \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u0442\u0435\u043c\u0430 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0442.\u0434.<\/p>\n<p>\u042d\u0442\u0430 \u043f\u0430\u043f\u043a\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442:<\/p>\n<ul>\n<li>\n<p>Config &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043d\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0431\u044d\u043a\u0435\u043d\u0434\u043e\u043c)<\/p>\n<\/li>\n<li>\n<p>Constants &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0430\u0445 \u0438 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f\u0445)<\/p>\n<\/li>\n<li>\n<p>Hooks &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u0445\u0443\u043a\u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u0445\u0443\u043a\u0438 (\u0445\u0443\u043a\u0438, \u0447\u0442\u043e \u0431\u044b\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u0432\u0430\u043c\u0438).<\/p>\n<\/li>\n<li>\n<p>Models &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043c\u043e\u0434\u0435\u043b\u0438, \u0447\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0441 \u0431\u044d\u043a\u0435\u043d\u0434\u0430.<\/p>\n<\/li>\n<li>\n<p>Schemes &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0441\u0445\u0435\u043c\u044b \u0444\u043e\u0440\u043c, \u0442\u0430\u0431\u043b\u0438\u0446 \u0438 \u0442.\u0434.<\/p>\n<\/li>\n<li>\n<p>Services &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0441\u0430\u043c\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u044b, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0431\u044d\u043a\u0435\u043d\u0434\u043e\u043c.<\/p>\n<\/li>\n<li>\n<p>Store &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0441\u0445\u0435\u043c\u044b \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 (\u0435\u0441\u043b\u0438 \u0412\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 MobX), \u0435\u0441\u043b\u0438 \u0436\u0435 \u0432\u044b \u043e\u0442\u0434\u0430\u0435\u0442\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0435 Redux, \u0442\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u043c\u043e\u0433\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u044d\u043a\u0448\u0435\u043d\u044b, \u0440\u0435\u0434\u044c\u044e\u0441\u0435\u0440\u044b \u0438 \u0442.\u0434.<\/p>\n<\/li>\n<li>\n<p>Theme (\u0434\u043b\u044f Styled-Components) &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0442\u0435\u043c\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>Types &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0434\u0443\u043b\u0435\u0439.<\/p>\n<\/li>\n<li>\n<p>Utils &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435, \u043f\u0440\u043e\u0441\u0442\u044b\u0435, \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0445\u0443\u043a\u0430\u0445, \u043b\u0438\u0431\u043e \u0436\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u0445.<\/p>\n<\/li>\n<li>\n<p>api.ts &#8212; \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 HTTP \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 axios), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u0443\u0442\u0438\u0440\u0443\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b (\u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043a\u0430\u043a\u0438\u0445-\u043b\u0438\u0431\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440).<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043f\u0430\u043f\u043e\u043a<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">\/\/ config\/api.config.ts  export const serverURI = \"http:\/\/localhost:8080\"; export const routesPrefix = '\/api\/v1';   \/\/ config\/routes.config.ts  import { routesPrefix } from \".\/api.config\";  export const productBrowserRoutes = { \tgetOne: (to: string = \":code\") =&gt; `\/product\/${to}`, \tsearch: (param: string = \":search\") =&gt; `\/search\/${param}`, };  export const productAPIRoutes = { \tgetOne: (code: string) =&gt; `${routesPrefix}\/product\/code\/${code}`, \tsearch: () =&gt; `${routesPrefix}\/product\/search`, };<\/code><\/pre>\n<p>\u0414\u043e\u0432\u043e\u043b\u044c\u043d\u043e-\u0442\u0430\u043a\u0438 \u0443\u0434\u043e\u0431\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0440\u043e\u0443\u0442\u044b \u0432 \u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435. \u0415\u0441\u043b\u0438 \u0432\u0434\u0440\u0443\u0433 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0431\u044d\u043a\u0435\u043d\u0434\u0430 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u0441\u044f \u0440\u043e\u0443\u0442\u044b, \u0442\u043e \u0438\u0445 \u043b\u0435\u0433\u043a\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0432 \u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u043d\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0441\u044c, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c, \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443. <\/p>\n<pre><code class=\"javascript\">\/\/ constants\/message.constants.ts  export const UNKNOWN_ERROR = \"\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430\";<\/code><\/pre>\n<pre><code class=\"javascript\">\/\/ hooks\/useAPI.ts \/\/ \u0425\u0443\u043a \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438 \/* eslint-disable react-hooks\/exhaustive-deps *\/  import { useCallback, useEffect } from \"react\"; import { useLocalObservable } from \"mobx-react-lite\"; import type { API, Schema, Take } from \"@core\/types\";  function useAPI&lt; \tF extends API.Service.Function&lt;API.Response&lt;any&gt;&gt;, \tR extends Take.FromServiceFunction.Response&lt;F&gt;, \tP extends Parameters&lt;F&gt; &gt;(service: F, { isPendingAfterMount = false, isIgnoreHTTPErrors = false }: Options = {}) { \tconst localStore = useLocalObservable&lt;Store&gt;(() =&gt; ({ \t\tisPending: { \t\t\tvalue: isPendingAfterMount, \t\t\tset: function (value) { \t\t\t\tthis.value = value; \t\t\t}, \t\t}, \t}));  \tconst call = useCallback( \t\tasync (...params: P): Promise&lt;R[\"result\"]&gt; =&gt; { \t\t\tlocalStore.isPending.set(true);  \t\t\ttry { \t\t\t\tconst { data } = await service(...params); \t\t\t\tconst { result } = data;  \t\t\t\tlocalStore.isPending.set(false);  \t\t\t\treturn result; \t\t\t} catch (error) { \t\t\t\tif (isIgnoreHTTPErrors === false) { \t\t\t\t\tconsole.error(error); \t\t\t\t}  \t\t\t\tlocalStore.isPending.set(false);  \t\t\t\tthrow error; \t\t\t} \t\t}, \t\t[service, isIgnoreHTTPErrors] \t);  \tconst isPending = useCallback(() =&gt; { \t\treturn localStore.isPending.value; \t}, []);  \tuseEffect(() =&gt; { \t\tlocalStore.isPending.set(isPendingAfterMount); \t}, [isPendingAfterMount]);  \treturn { \t\tcall, \t\tisPending, \t}; }  export { useAPI }; export interface Options { \tisPendingAfterMount?: boolean; \tisIgnoreHTTPErrors?: boolean; }  type Store = Schema.Store&lt;{ isPending: boolean }&gt;;<\/code><\/pre>\n<pre><code class=\"javascript\">\/\/ models\/product.model.ts \/\/ \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0442\u043e\u0432\u0430\u0440\u0430  export interface ProductModel { \tid: number; \tname: string; \tcode: string; \tinfo: { \t\tdescription: string;<\/code><\/pre>\n<\/div>\n<\/details>\n<p><\/br><\/p>\n<p><\/br><\/br><\/br><\/p>\n<\/div>\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-319264","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/319264","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=319264"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/319264\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=319264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=319264"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=319264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}