{"id":406443,"date":"2024-06-29T18:56:50","date_gmt":"2024-06-29T18:56:50","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=406443"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=406443","title":{"rendered":"<span>React: \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439<\/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\/4q\/dj\/sj\/4qdjsje-cdcxxlo7dj9n2thrvke.png\" data-src=\"https:\/\/habrastorage.org\/webt\/4q\/dj\/sj\/4qdjsje-cdcxxlo7dj9n2thrvke.png\"\/>  <\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0442, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u043c &#171;\u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0435&#187; \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0430\u043c, \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435, \u043d\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c <code>React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0431\u0435\u0433\u0430\u044f \u0432\u043f\u0435\u0440\u0435\u0434, \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0447\u0443\u0442\u044c \u043c\u0435\u043d\u0435\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c, \u0447\u0435\u043c &#171;\u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435&#187; \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 \u0445\u0443\u043a\u0430 <code>useReducer()<\/code> \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 <code>Context API<\/code> (\u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0438 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u044f\u0434\u0440\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f).<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u043e\u0432, \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043d\u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c <code>React<\/code>, \u0438 \u0432\u043e \u043c\u043d\u043e\u0433\u043e\u043c \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u043b\u0435\u043d\u043e <a href=\"https:\/\/vuex.vuejs.org\/ru\/guide\/\"><code>Vuex<\/code><\/a> \u2014 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c <code>Vue-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u043c \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u0434\u0438\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442\u0441\u044f \u043b\u044e\u0431\u044b\u0435 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f \u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043b\u044e\u0431\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u043a\u0440\u0438\u0442\u0438\u043a\u0430.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u043a\u0430 \u043c\u043d\u0435 \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043b\u043e\u0441\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438\u0441\u043f\u044b\u0442\u0430\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 &#171;\u043f\u043e\u043b\u0435\u0432\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445&#187; (\u044f \u043d\u0430\u043c\u0435\u0440\u0435\u043d \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0443\u0434\u043e\u0431\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435), \u043d\u043e \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043e\u043d\u043e \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043b\u044e\u0431\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438 \u0441\u043e\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u0438 \u0434\u0432\u0443\u0445 \u0432\u0430\u0436\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439:<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<ol>\n<li>\u0412 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 (<code>store<\/code>) \u0434\u043e\u043b\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435. \u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0443\u0442\u043e\u043c\u043b\u044f\u0442\u044c \u0432\u0430\u0441 \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u044f\u043c\u0438 \u043d\u0430 \u0442\u0435\u043c\u0443 &#171;\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f? \u041a\u0430\u043a\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u043c, \u0430 \u043a\u0430\u043a\u043e\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u043c?&#187; \u0438 \u0442.\u0434. \u041b\u0438\u0447\u043d\u043e \u044f \u0438\u0441\u0445\u043e\u0436\u0443 \u0438\u0437 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u043b\u044e\u0431\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u043c, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0434\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0435, \u0442.\u0435. \u043f\u043e\u043a\u0430 \u043d\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u0435\u0433\u043e \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438.<\/li>\n<li>\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0431\u043b\u0438\u0437\u043a\u043e \u043a \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c, \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u044e\u0449\u0438\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442. \u042d\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043b\u043b\u043e\u043a\u0430\u0446\u0438\u0435\u0439 (collocation) \u0438\u043b\u0438 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435\u043c \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u041b\u043e\u0433\u0438\u043a\u0430 \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043e \u0442\u043e\u043c, \u043a\u0430\u043a\u0438\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0433\u0434\u0435 \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/li>\n<\/ol>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/gz\/_o\/yx\/gz_oyx9xhm_7wvpydh1uk1wc3wy.jpeg\" data-src=\"https:\/\/habrastorage.org\/webt\/gz\/_o\/yx\/gz_oyx9xhm_7wvpydh1uk1wc3wy.jpeg\" data-blurred=\"true\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0430:<\/p>\n<p>  <\/p>\n<div class=\"oembed\">\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/615fdf7fedd610f626b80cb1\" data-style=\"\" id=\"615fdf7fedd610f626b80cb1\" width=\"\"><\/div>\n<\/div>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>: \u0441\u0442\u0430\u0442\u044c\u044f \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u0430 \u043d\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u044e\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u044b\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 <code>React<\/code>, \u0443\u0441\u0442\u0430\u0432\u0448\u0438\u0445 \u043e\u0442 <code>Redux<\/code> \u0438 \u0438\u0436\u0435 \u0441 \u043d\u0438\u043c ?<\/p>\n<p>  <\/p>\n<h2 id=\"rezultat\">\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/h2>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435. \u0418 \u043f\u043e\u0447\u0435\u043c\u0443 \u043d\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0433\u043e\u0442\u043e\u0432\u044b\u043c\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c\u0438? \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u0437\u0430\u0447\u0435\u043c \u043d\u0430\u043c \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u0442\u044c \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434, \u043a\u043e\u0433\u0434\u0430, \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u0432\u0441\u0435 \u0434\u0430\u0432\u043d\u043e \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043d\u043e \u0443\u043c\u043d\u044b\u043c\u0438 \u043b\u044e\u0434\u044c\u043c\u0438?<\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u044a\u044f\u0441\u043d\u044e \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438\u2026 \u043a\u043e\u0434\u043e\u043c. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c &#171;\u0442\u0443\u0434\u0443\u0448\u043a\u0443&#187; \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u2014 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f;<\/li>\n<li>\u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u043e\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f;<\/li>\n<li>\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438: \u0435\u0435 \u0442\u0435\u043a\u0441\u0442\u0430, \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u2014 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435;<\/li>\n<li>\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u2014 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f;<\/li>\n<li>\u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f \u0437\u0430\u0434\u0430\u0447 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435: \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445, \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0445 \u0438\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u2014 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f;<\/li>\n<li>\u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u2014 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f;<\/li>\n<li>\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u2014 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f;<\/li>\n<li>\u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 (\u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445) \u2014 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f;<\/li>\n<li>\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438: \u043e\u0431\u0449\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0445 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u2014 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f;<\/li>\n<li>\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439: \u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0437\u0430\u0434\u0430\u0447 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0437\u0430\u0434\u0430\u0447 \u0432 \u0411\u0414 \u0438\u043b\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u0448\u0435\u0439 \u043e\u0448\u0438\u0431\u043a\u0435 \u2014 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b, \u0441\u043b\u0435\u0434\u0443\u044f \u0432\u0441\u0435\u043c \u043a\u0430\u043d\u043e\u043d\u0430\u043c \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e <a href=\"https:\/\/redux.js.org\/\"><code>Redux<\/code><\/a> \u0432 \u043b\u0438\u0446\u0435 <a href=\"https:\/\/redux-toolkit.js.org\/\"><code>Redux Toolkit<\/code><\/a>, \u0442\u043e \u043a\u043e\u0434 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import {  configureStore,  createAsyncThunk,  createEntityAdapter,  createSelector,  createSlice } from '@reduxjs\/toolkit' \/\/ \u0423\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 import axios from 'axios'  \/\/ \u0410\u0434\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 const SERVER_URL = 'http:\/\/localhost:5000\/todos'  \/\/ \u0422\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 (entity adapter) (\u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447) const todoAdapter = createEntityAdapter()  \/\/ \u041d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 (\u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447) const initialTodoState = todoAdapter.getInitialState({  \/\/ \u0441\u0442\u0430\u0442\u0443\u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f  status: 'idle',  \/\/ \u0441\u0442\u0430\u0442\u0443\u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f  message: {} })  \/\/ \u0422\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c (thunk) - \/\/ \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 export const fetchTodos = createAsyncThunk('todos\/fetchTodos', async () => {  try {    \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435    const { data: todos } = await axios(SERVER_URL)    \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u0443\u0441\u043f\u0435\u0445\u0435    return {      todos,      message: { type: 'success', text: 'Todos loaded' }    }  } catch (err) {    console.error(err.toJSON())    \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435    return {      message: { type: 'error', text: 'Something went wrong' }    }  } })  \/\/ \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 \u0432 \u0411\u0414 export const saveTodos = createAsyncThunk(  'todos\/saveTodos',  async (newTodos) => {    try {      \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438      const { data: existingTodos } = await axios(SERVER_URL)       \/\/ \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u0445      for (const todo of existingTodos) {        \/\/ \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c `URL` \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438        const todoUrl = `${SERVER_URL}\/${todo.id}`         \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c, \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043b\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0441\u0440\u0435\u0434\u0438 \u043d\u043e\u0432\u044b\u0445        const commonTodo = newTodos.find((_todo) => _todo.id === todo.id)         \/\/ \u0435\u0441\u043b\u0438 \u0438\u043c\u0435\u0435\u0442\u0441\u044f        if (commonTodo) {          \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439          if (            !Object.entries(commonTodo).every(              ([key, value]) => value === todo[key]            )          ) {            \/\/ \u0435\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0435\u0441\u0442\u044c, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0443 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435,            await axios.put(todoUrl, commonTodo)          }        } else {          \/\/ \u0435\u0441\u043b\u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f          \/\/ \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0443 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435          await axios.delete(todoUrl)        }      }       \/\/ \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c \u0438\u0445 \u0441 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438      for (const todo of newTodos) {        \/\/ \u0435\u0441\u043b\u0438 \u043d\u043e\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0435\u0442 \u0441\u0440\u0435\u0434\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445        \/\/ \u0437\u043d\u0430\u0447\u0438\u0442, \u043e\u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u043e\u0432\u0430\u044f        if (!existingTodos.find((_todo) => _todo.id === todo.id)) {          \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0435 \u0432 \u0411\u0414          await axios.post(SERVER_URL, todo)        }      }      \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u0443\u0441\u043f\u0435\u0445\u0435      return { type: 'success', text: 'Todos saved' }    } catch (err) {      console.error(err.toJSON())      \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435      return {        type: 'error',        text: 'Something went wrong'      }    }  } )  \/\/ \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 - \/\/ \u043e\u043d\u0430 \u043d\u0443\u0436\u043d\u0430 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 export const giveMeSomeTime = createAsyncThunk(  'todos\/giveMeSomeTime',  async (ms) =>    await new Promise((resolve) => {      const timerId = setTimeout(() => {        resolve()        clearTimeout(timerId)      }, ms)    }) )  \/\/ \u0422\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0438\u043b\u0438 \u0441\u0440\u0435\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f (\u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447) const todoSlice = createSlice({  \/\/ \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435  name: 'todos',  \/\/ \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 \u0432\u0438\u0434\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b  initialState: initialTodoState,  \/\/ \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u044b  reducers: {    \/\/ \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438    addTodo: todoAdapter.addOne,    \/\/ \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438    updateTodo: todoAdapter.updateOne,    \/\/ \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438    removeTodo: todoAdapter.removeOne,    \/\/ \u0434\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447    completeAllTodos(state) {      Object.values(state.entities).forEach((todo) => {        todo.done = true      })    },    \/\/ \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447    clearCompletedTodos(state) {      const completedTodoIds = Object.values(state.entities)        .filter((todo) => todo.done)        .map((todo) => todo.id)      todoAdapter.removeMany(state, completedTodoIds)    }  },  \/\/ \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u044b \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439  extraReducers: (builder) => {    builder      \/\/ \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f      .addCase(fetchTodos.pending, (state) => {        \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438        state.status = 'loading'      })      \/\/ \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d      .addCase(fetchTodos.fulfilled, (state, { payload }) => {        if (payload.todos) {          \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447          todoAdapter.setAll(state, payload.todos)        }        \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435        state.message = payload.message        \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438        state.status = 'idle'      })      \/\/ \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447 \u0432 \u0411\u0414 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f      .addCase(saveTodos.pending, (state) => {        \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438        state.status = 'loading'      })      \/\/ \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d      .addCase(saveTodos.fulfilled, (state, { payload }) => {        \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435        state.message = payload        \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438        state.status = 'idle'      })      \/\/ \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d      .addCase(giveMeSomeTime.fulfilled, (state) => {        \/\/ \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435        state.message = {}      })  } })  \/\/ \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438 export const {  addTodo,  updateTodo,  removeTodo,  completeAllTodos,  clearCompletedTodos } = todoSlice.actions  \/\/ \u041d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 (\u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430) const initialFilterState = {  status: 'all' }  \/\/ \u0427\u0430\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f (\u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430) const filterSlice = createSlice({  \/\/ \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435  name: 'filter',  \/\/ \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435  initialState: initialFilterState,  \/\/ \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u044b  reducers: {    \/\/ \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430    setFilter(state, action) {      state.status = action.payload    }  } })  \/\/ \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430 export const { setFilter } = filterSlice.actions  \/\/ \u0422\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0432\u0441\u0435\u0445 \u0437\u0430\u0434\u0430\u0447 \u0438 \u0438\u0445 \u043e\u0431\u0449\u0435\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 export const { selectAll, selectTotal } = todoAdapter.getSelectors(  (state) => state.todos )  \/\/ \u0421\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0437\u0430\u0434\u0430\u0447 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430 export const selectFilteredTodos = createSelector(  selectAll,  (state) => state.filter,  (todos, filter) => {    const { status } = filter    if (status === 'all') return todos    return status === 'active'      ? todos.filter((todo) => !todo.done)      : todos.filter((todo) => todo.done)  } )  \/\/ \u0421\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 export const selectTodoStats = createSelector(  selectAll,  selectTotal,  (todos, total) => {    const completed = todos.filter((todo) => todo.done).length    const active = total - completed    const percent = total === 0 ? 0 : Math.round((active \/ total) * 100)     return {      total,      completed,      active,      percent    }  } )  \/\/ \u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 export const store = configureStore({  reducer: {    todos: todoSlice.reducer,    filter: filterSlice.reducer  } })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u043d\u043e \u043e\u0447\u0435\u043d\u044c \u043c\u0430\u043b\u043e \u0441\u043c\u044b\u0441\u043b\u0430. \u0418 \u044d\u0442\u043e \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439 <code>Redux<\/code>! \u041d\u0430 \u0440\u0430\u0431\u043e\u0442\u0435 \u0432\u0430\u043c, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f (\u0438\u043b\u0438 \u0435\u0449\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f) \u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f \u0441\u043e \u0441\u0442\u0430\u0440\u044b\u043c-\u0434\u043e\u0431\u0440\u044b\u043c &#171;\u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u043c&#187; <code>Redux<\/code> (\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432\u044b\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438, \u0431\u0443\u0434\u044c \u043e\u043d\u0438 \u043d\u0435\u043b\u0430\u0434\u043d\u044b).<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0442\u0443\u0434\u0443\u0448\u043a\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 <code>useReducer()<\/code> \u0438 <code>Context API<\/code> (\u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0430\u0440\u043e\u0447\u043a\u0438 &#171;\u0445\u0430\u043a\u043e\u0432&#187;), \u043a\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u0438\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { createContext, useContext, useReducer, useMemo } from 'react' import axios from 'axios'  const SERVER_URL = 'http:\/\/localhost:5000\/todos'  \/\/ \u041a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b const SET_TODOS = 'SET_TODOS' const SET_STATUS = 'SET_STATUS' const ADD_TODO = 'ADD_TODO' const UPDATE_TODO = 'UPDATE_TODO' const REMOVE_TODO = 'REMOVE_TODO' const COMPLETE_TODOS = 'COMPLETE_TODOS' const CLEAR_COMPLETED = 'CLEAR_COMPLETED' const SET_FILTER = 'SET_FILTER' const SET_MESSAGE = 'SET_MESSAGE'  \/\/ \u0420\u0435\u0434\u0443\u043a\u0442\u043e\u0440 const reducer = (state, { type, payload }) => {  switch (type) {    case SET_TODOS:      return {        ...state,        todos: payload      }    case SET_STATUS:      return {        ...state,        status: payload      }    case ADD_TODO:      return { ...state, todos: state.todos.concat(payload) }    case UPDATE_TODO:      return {        ...state,        todos: state.todos.map((todo) =>          todo.id === payload.id ? { ...todo, ...payload.changes } : todo        )      }    case REMOVE_TODO:      return {        ...state,        todos: state.todos.filter((todo) => todo.id !== payload)      }    case COMPLETE_TODOS:      return { ...state, todos: state.todos.map((todo) => todo.done === true) }    case CLEAR_COMPLETED:      return {        ...state,        todos: state.todos.filter((todo) => todo.done === true)      }    case SET_FILTER:      return {        ...state,        filter: payload      }    case SET_MESSAGE:      return {        ...state,        message: payload      }    default:      return state  } }  \/\/ \u0417\u0430\u0434\u0435\u0440\u0436\u043a\u0430 const giveMeSomeTime = async () =>  await new Promise((resolve) => {    const timerId = setTimeout(() => {      resolve()      clearTimeout(timerId)    }, 2000)  })  \/\/ \u0422\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 (\u0445\u0430\u043a \u043d\u043e\u043c\u0435\u0440 \u0440\u0430\u0437) const createActions = (dispatch) => ({  setTodos: (todos) => ({    type: SET_TODOS,    payload: todos  }),  setStatus: (status) => ({    type: SET_STATUS,    payload: status  }),  addTodo: (todo) => ({    type: ADD_TODO,    payload: todo  }),  updateTodo: (payload) => ({    type: UPDATE_TODO,    payload  }),  removeTodo: (todoId) => ({    type: REMOVE_TODO,    payload: todoId  }),  completeTodos: () => ({    type: COMPLETE_TODOS  }),  clearCompleted: () => ({    type: COMPLETE_TODOS  }),  setFilter: (filter) => ({    type: SET_FILTER,    payload: filter  }),  setMessage: (message) => ({    type: SET_MESSAGE,    payload: message  }),  async fetchTodos() {    dispatch(this.setStatus('loading'))     try {      const { data: todos } = await axios(SERVER_URL)       dispatch(this.setTodos(todos))       dispatch(        this.setMessage({ type: 'success', text: 'Todos loaded' })      )    } catch (err) {      console.error(err.toJSON())       dispatch(        this.setMessage({          type: 'error',          text: 'Something went wrong'        })      )    } finally {      dispatch(this.setStatus('idle'))       await giveMeSomeTime()       dispatch(this.setMessage({}))    }  },  async saveTodos(newTodos) {    dispatch(this.setStatus('loading'))     try {      const { data: existingTodos } = await axios(SERVER_URL)       for (const todo of existingTodos) {        const todoUrl = `${SERVER_URL}\/${todo.id}`         const commonTodo = newTodos.find((_todo) => _todo.id === todo.id)         if (commonTodo) {          if (            !Object.entries(commonTodo).every(              ([key, value]) => value === todo[key]            )          ) {            await axios.put(todoUrl, commonTodo)          }        } else {          await axios.delete(todoUrl)        }      }       for (const todo of newTodos) {        if (!existingTodos.find((_todo) => _todo.id === todo.id)) {          await axios.post(SERVER_URL, todo)        }      }       dispatch(        this.setMessage({ type: 'success', text: 'Todos saved' })      )    } catch (err) {      console.error(err.toJSON())       dispatch(        this.setMessage({          type: 'error',          text: 'Something went wrong'        })      )    } finally {      dispatch(this.setStatus('idle'))       await giveMeSomeTime()       dispatch(this.setMessage({}))    }  } })  \/\/ \u0422\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u044c \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 (\u0445\u0430\u043a \u043d\u043e\u043c\u0435\u0440 \u0434\u0432\u0430) const createSelectors = (state) => ({  selectFilteredTodos() {    const { todos, filter } = state    if (filter === 'all') return todos    return filter === 'active'      ? todos.filter((todo) => !todo.done)      : todos.filter((todo) => todo.done)  },  selectTodoStats() {    const { todos } = state    const { length } = todos     const completed = todos.filter((todo) => todo.done).length    const active = length - completed    const percent = length === 0 ? 0 : Math.round((active \/ length) * 100)     return {      total: length,      completed,      active,      percent    }  } })  \/\/ \u041d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 const initialState = {  todos: [],  status: 'idle',  filter: 'all',  message: {} }  \/\/ \u041a\u043e\u043d\u0442\u0435\u043ac\u0442 const Context = createContext()  \/\/ \u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 export const Provider = ({ children }) => {  const [state, dispatch] = useReducer(reducer, initialState)   \/\/ \u041d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043f\u0440\u0435\u0436\u0434\u0435\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f  \/\/ \u044d\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0438 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f  \/\/ \u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043f\u044b\u0442\u043d\u044b\u043c \u043f\u0443\u0442\u0435\u043c  const actions = useMemo(() => createActions(dispatch), [])  const selectors = createSelectors(state)   return (    &lt;Context.Provider value={{ state, dispatch, actions, selectors }}>      {children}    &lt;\/Context.Provider>  ) }  \/\/ \u0425\u0443\u043a \u0434\u043b\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 export const useAppContext = () => useContext(Context)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043c\u043d\u043e\u0433\u043e \u043b\u0443\u0447\u0448\u0435 \u043a\u0430\u043a \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u0438 \u043a\u043e\u0434\u0430, \u0442\u0430\u043a \u0438, \u0447\u0442\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0432\u0430\u0436\u043d\u043e, \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041d\u043e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b! \u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435, \u0431\u0435\u0437 \u043d\u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c. \u041d\u043e \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440! \u041a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0431\u0435\u0437 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u0430 \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u043d\u0435\u043b\u044c\u0437\u044f. \u0418\u043b\u0438 \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u043c\u043e\u0436\u043d\u043e? \u0412\u043f\u043e\u043b\u043d\u0435. \u0410 \u0447\u0442\u043e \u043d\u0430\u0441\u0447\u0435\u0442 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u0430? \u041c\u043e\u0436\u043d\u043e \u043b\u0438 \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0431\u0435\u0437 \u043d\u0435\u0433\u043e? \u041d\u0435\u0442, \u0431\u0435\u0437 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u0430 \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c <code>React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/code> \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u0433\u043e. \u041d\u043e \u0435\u0433\u043e, \u043a\u0430\u043a \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0434\u0430\u043b\u044c\u0448\u0435, \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u044f\u0432\u043d\u043e\u043c \u0432\u0438\u0434\u0435.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0442\u0443\u0434\u0443\u0448\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0435\u0449\u0435 \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b\u0438, \u043d\u043e \u0441\u043a\u043e\u0440\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0442\u043e \u043a\u043e\u0434 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import axios from 'axios' axios.defaults.baseURL = 'http:\/\/localhost:5000\/todos'  const sleep = (ms) =>  new Promise((resolve) => {    const timerId = setTimeout(() => {      resolve()      clearTimeout(timerId)    }, ms)  })  const store = {  state: {    todos: [],    status: 'idle',    filter: 'all',    message: {}  },  setters: {    setStatus: (_, status) => ({ status }),    setMessage: (_, message) => ({ message }),    setTodos: (_, newTodos) => ({ todos: newTodos }),    addTodo: ({ todos }, newTodo) => ({ todos: todos.concat(newTodo) }),    updateTodo: ({ todos }, { id, changes }) => ({      todos: todos.map((todo) =>        todo.id === id          ? {              ...todo,              ...changes            }          : todo      )    }),    removeTodo: ({ todos }, todoId) => {      return {        todos: todos.filter((todo) => todo.id !== todoId)      }    },    completeTodos: ({ todos }) => ({      todos: todos.map((todo) => ({ ...todo, done: true }))    }),    clearCompleted: ({ todos }) => ({ todos: todos.filter((todo) => !todo.done) }),    setFilter: (_, filter) => ({ filter })  },  getters: {    getFilteredTodos: ({ todos, filter }) => {      if (filter === 'all') return todos      return filter === 'active'        ? todos.filter((todo) => !todo.done)        : todos.filter((todo) => todo.done)    },    getTodoStats: ({ todos }) => {      const { length } = todos       const completed = todos.filter((todo) => todo.done).length      const active = length - completed      const percent = length === 0 ? 0 : Math.round((active \/ length) * 100)       return {        total: length,        completed,        active,        percent      }  },  actions: {    async fetchTodos({ setStatus, setTodos, setMessage }) {      setStatus('loading')       try {        const { data } = await axios()        setTodos(data)        setMessage({          type: 'success',          text: 'Todos received'        })      } catch (err) {        console.error(err.toJSON())        setMessage({          type: 'error',          text: 'Something went wrong'        })      } finally {        setStatus('idle')        await sleep(1000)        setMessage({})      }    },    async saveTodos({ setStatus, setMessage }, newTodos) {      setStatus('loading')      try {        const { data: existingTodos } = await axios()         for (const todo of existingTodos) {          const commonTodo = newTodos.find((_todo) => _todo.id === todo.id)           if (commonTodo) {            if (              !Object.entries(commonTodo).every(                ([key, value]) => value === todo[key]              )            ) {              await axios.put(todo.id, commonTodo)            }          } else {            await axios.delete(todo.id)          }        }         for (const todo of newTodos) {          if (!existingTodos.find((_todo) => _todo.id === todo.id)) {            await axios.post('\/', todo)          }        }         setMessage({ type: 'success', text: 'Todos saved' })      } catch (err) {        console.error(err.toJSON())        setMessage({          type: 'error',          text: 'Something went wrong'        })      } finally {        setStatus('idle')        await sleep(1000)        setMessage({})      }    }  } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 &#171;\u0440\u0430\u0437\u043d\u0435\u0441\u0442\u0438&#187; \u0441\u0435\u0442\u0442\u0435\u0440\u044b, \u0433\u0435\u0442\u0442\u0435\u0440\u044b \u0438 \u044d\u043a\u0448\u0435\u043d\u044b \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0444\u0430\u0439\u043b\u0430\u043c, \u0442\u043e \u043a\u043e\u0434 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { unpackModule } from '.\/context' import * as setters from '.\/setters' import * as getters from '.\/getters' import * as actions from '.\/actions'  const store = {  state: {    todos: [],    status: 'idle',    filter: 'all',    message: {}  },  setters: unpackModule(setters),  getters: unpackModule(getters),  actions: unpackModule(actions) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u043e, \u0447\u0442\u043e \u0434\u043e\u043a\u0442\u043e\u0440 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0431\u043e \u0432\u0441\u0435\u043c \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443.<\/p>\n<p>  <\/p>\n<h2 id=\"koncepciya\">\u041a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f<\/h2>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u0432\u0441\u043b\u0443\u0445.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c \u043d\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043d\u0435\u043a\u0430\u044f \u0433\u0438\u0431\u043a\u0430\u044f \u0438 \u043b\u0435\u0433\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430. \u0412 <code>JavaScript<\/code> \u043d\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0447\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u044d\u0442\u043e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u043c \u2014 <code>store<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u043e\u043b\u0436\u043d\u0430 \u043e\u0441\u0442\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043b\u043e\u0441\u043a\u043e\u0439, \u0442.\u0435. \u043e\u0434\u043d\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0439: \u044d\u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442 \u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u0434\u0438\u0444\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0435\u0442\u0442\u0435\u0440\u0430\u043c\u0438 (<code>setters<\/code>), \u0430 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u2014 \u044d\u043a\u0448\u0435\u043d\u0430\u043c\u0438 (<code>actions<\/code>).<\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a\u0443\u044e \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443 \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u0441\u0435\u0442\u0442\u0435\u0440\u044b \u0438 \u044d\u043a\u0448\u0435\u043d\u044b?<\/p>\n<p>  <\/p>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0441\u0435\u0442\u0442\u0435\u0440\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0438 \u0438\u043c\u0435\u0442\u044c <em>\u043f\u0440\u044f\u043c\u043e\u0439<\/em> \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e \u0434\u043b\u044f \u0435\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0441\u0435\u0442\u0442\u0435\u0440\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 \u0432\u0438\u0434\u0435 \u0447\u0430\u0441\u0442\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0442.\u0435. \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u043a\u043b\u044e\u0447\u043e\u043c, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u042f \u043f\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0448\u0435\u043b \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0447\u0430\u0441\u0442\u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u0441\u0435\u0442\u0442\u0435\u0440\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u0421\u0445\u0435\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \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\">setSomething: (state, args) => ({ stateSlice: newState }) \/\/ \u0438\u043b\u0438 setSomething(state, args) {  return {    stateSlice: newState  } } \/\/ \u043c\u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u043b\u0438, \u043a\u043e\u0433\u0434\u0430 \u0441\u0435\u0442\u0442\u0435\u0440 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">setSomething: (_, args) => ({ stateSlice: newState })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u043b\u0438, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0447\u0430\u0441\u0442\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f (\u043a\u043b\u044e\u0447\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f):<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">setSomething: (_, arg) => ({ arg })<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043f\u0435\u0440\u0432\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c\u044b\u043c \u0441\u0435\u0442\u0442\u0435\u0440\u043e\u043c, \u0432\u0441\u0435\u0433\u0434\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/li>\n<li>\u0441\u0435\u0442\u0442\u0435\u0440\u0443 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043b\u044e\u0431\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432<\/li>\n<li>\u0441\u0435\u0442\u0442\u0435\u0440 \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0444\u043e\u0440\u043c\u044b (\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u0432\u044b\u0448\u0435)<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u042d\u043a\u0448\u0435\u043d\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u043d\u043e \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e. \u0414\u043e\u0441\u0442\u0443\u043f \u044d\u043a\u0448\u0435\u043d\u043e\u0432 \u043a \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e \u043e\u043f\u043e\u0441\u0440\u0435\u0434\u043e\u0432\u0430\u043d \u0441\u0435\u0442\u0442\u0435\u0440\u0430\u043c\u0438, \u0442.\u0435. \u044d\u043a\u0448\u0435\u043d\u044b \u043c\u0435\u043d\u044f\u044e\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0442\u0442\u0435\u0440\u044b. \u042d\u043a\u0448\u0435\u043d\u044b \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0438\u0447\u0435\u0433\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c. \u0421\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">async fetchSomething(setters, args) {  const result = await fetchSomething(args)  setters.setSomething(result) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438\u043b\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u044d\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0433\u0435\u0442\u0442\u0435\u0440\u0430\u043c\u0438 \u2014 <code>getters<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0413\u0435\u0442\u0442\u0435\u0440\u044b \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438 \u0438\u043c\u0435\u044e\u0442 <em>\u043f\u0440\u044f\u043c\u043e\u0439<\/em> \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0446\u0435\u043b\u044c \u0433\u0435\u0442\u0442\u0435\u0440\u043e\u0432 \u2014 \u0434\u0430\u0436\u0435 \u043d\u0435 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0447\u0430\u0441\u0442\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f (\u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e\u0441\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435), \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0433\u0435\u0442\u0442\u0435\u0440\u0430\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435, \u0442.\u0435. \u0432 \u0432\u0438\u0434\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439. \u0422\u0430\u043a\u0436\u0435, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0433\u0435\u0442\u0442\u0435\u0440\u044b \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u043c \u0434\u0440\u0443\u0433\u0438\u0435 \u0433\u0435\u0442\u0442\u0435\u0440\u044b (<code>DRY<\/code>). \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0433\u0435\u0442\u0442\u0435\u0440\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0447\u0430\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438\u043b\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u0421\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">getSomething: ({ stateSlice1, stateSlice2, ...stateSliceN, getters }) => stateSice | derivedData<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>: \u0433\u0435\u0442\u0442\u0435\u0440\u044b \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u044b \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439.<\/p>\n<p>  <\/p>\n<h2 id=\"realizaciya\">\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h2>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f, \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>createSimpleContext()<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0434\u0432\u0443\u043c\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438: \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u0445\u0443\u043a\u043e\u043c \u0434\u043b\u044f \u0435\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const store = {  state: {    todos: [],    status: 'idle',    filter: 'all',    message: {}  },  setters: unpackModule(setters),  getters: unpackModule(getters),  actions: unpackModule(actions) }  export const [SimpleProvider, useSimpleContext] = createSimpleContext(store)<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u0420\u0435\u043c\u0430\u0440\u043a\u0430<\/em>: \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>unpackModule()<\/code> \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u044f \u0432 \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const unpackModule = (module) => {  const obj = {}  for (const key in module) {    for (const _key in module[key]) {      obj[_key] = module[key][_key]    }  }  return obj }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0435\u0442\u0442\u0435\u0440\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u0442\u043e \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u0431\u0435\u0433\u0430\u0442\u044c \u043a \u043f\u043e\u043c\u043e\u0449\u0438 <code>unpackModule()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { setters } from '.\/setters' import { getters } from '.\/getters' import { actions } from '.\/actions'  const store = {  state: {    todos: [],    status: 'idle',    filter: 'all',    message: {}  },  setters,  getters,  actions }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0435\u0442\u0442\u0435\u0440\u044b \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0438\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { appSetters, todoSetters, filterSetters } from '.\/setters' import { getters } from '.\/getters' import { actions } from '.\/actions'  const store = {  state: {    todos: [],    status: 'idle',    filter: 'all',    message: {}  },  setters: {    ...appSetters,    ...todoSetters,    ...filterSetters  },  getters,  actions }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 <code>createSimpleContext()<\/code>? \u0412\u043e\u0442 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0435\u0435 \u043a\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { createContext, useContext, useState, useMemo } from 'react' import {  createSetters,  createGetters,  createActions,  unpackModule } from '.\/utils'  \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 export default function createSimpleContext(store) {  \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442  const SimpleContext = createContext()   \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440  \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b  const SimpleProvider = ({ children }) => {    const [simpleState, setSimpleState] = useState(store.state)     \/\/ \u043c\u0435\u043c\u043e\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0441\u0435\u0442\u0442\u0435\u0440\u043e\u0432 \u0438 \u044d\u043a\u0448\u0435\u043d\u043e\u0432    \/\/ \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u043c\u0438    \/\/ \u0437\u0434\u0435\u0441\u044c \u0443 \u0432\u0430\u0441 \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0441\u0435\u0442\u0442\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u0432\u0435\u0436\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435    \/\/ \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e `createSetters()` \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430    const setters = useMemo(      () => createSetters(store.setters, setSimpleState),      \/\/ eslint-disable-next-line      []    )    const actions = useMemo(      () => createActions(store.actions, setters),      \/\/ eslint-disable-next-line      []    )    \/\/ \u044f \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043b \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u043c\u0435\u043c\u043e\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0433\u0435\u0442\u0442\u0435\u0440\u043e\u0432 \u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u043c\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0430\u043a\u0443\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f    const getters = createGetters(store.getters, simpleState)     return (      \/\/ \u041c\u044b \u0432\u043f\u043e\u043b\u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0447\u0435\u0440\u0435\u0437 `simpleState` \u0438 `setSimpleState()`,      \/\/ \u043d\u043e \u043b\u0443\u0447\u0448\u0435 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u0435 \u043f\u0443\u0442\u0430\u043d\u0438\u0446\u044b \u043c\u0435\u0436\u0434\u0443 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438.      \/\/ \u042d\u0442\u0438\u043c \u0436\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u0441\u0435\u0442\u0442\u0435\u0440\u044b, \u0433\u0435\u0442\u0442\u0435\u0440\u044b \u0438 \u044d\u043a\u0448\u0435\u043d\u044b \u043b\u0443\u0447\u0448\u0435 \u043d\u0435 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0442\u044c      \/\/ \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442: \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, `setters.setTodos()` \u0438 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c,      \/\/ \u0447\u0442\u043e \u0438\u043c\u0435\u0435\u043c \u0434\u0435\u043b\u043e \u0441 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c      &lt;SimpleContext.Provider        value={{          simpleState,          setSimpleState,          setters,          getters,          actions        }}      >        {children}      &lt;\/SimpleContext.Provider>    )  }   \/\/ \u0425\u0443\u043a \u0434\u043b\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430  const useSimpleContext = () => useContext(SimpleContext)   return [SimpleProvider, useSimpleContext] }  export { unpackModule }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u0430\u043c\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u0438\u0437 \u0447\u0438\u0441\u043b\u0430 \u0443\u0442\u0438\u043b\u0438\u0442 \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>createActions()<\/code>. \u0421 \u043d\u0435\u0435 \u0438 \u043d\u0430\u0447\u043d\u0435\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u044d\u043a\u0448\u0435\u043d\u044b \u0438 \u0441\u0435\u0442\u0442\u0435\u0440\u044b export const createActions = (_actions, setters) => {  const actions = {}  \/\/ \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u044d\u043a\u0448\u0435\u043d\u0443 \u0441\u0435\u0442\u0442\u0435\u0440\u044b \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430.  \/\/ \u041f\u043e\u043b\u0430\u0433\u0430\u044e, \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0442\u0430\u043a\u043e\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u0430\u043a \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440,  \/\/ \u0442.\u0435. \u0434\u0435\u043a\u043e\u0440\u0438\u0440\u0443\u0435\u043c \u044d\u043a\u0448\u0435\u043d\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430.  \/\/ \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043c\u044b \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \"\u0430\u0440\u043d\u043e\u0441\u0442\u044c\" \u0444\u0443\u043d\u043a\u0446\u0438\u0438  for (const key in _actions) {    actions[key] = (...args) => _actions[key](setters, ...args)  }  return actions }<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>: \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0432\u044b\u0437\u043e\u0432\u0430 \u0443\u0442\u0438\u043b\u0438\u0442 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. <code>createActions()<\/code> \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u0435\u043a\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0442\u0442\u0435\u0440\u044b.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c <code>createGetters()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u041f\u043e \u0441\u0443\u0442\u0438, \u0432\u0441\u0435 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u043e\u0433\u043e, \/\/ \u0447\u0442\u043e \u043c\u044b \u0434\u0435\u043a\u043e\u0440\u0438\u0440\u0443\u0435\u043c \u0433\u0435\u0442\u0442\u0435\u0440\u044b \u0434\u0432\u0430\u0436\u0434\u044b: \/\/ \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430, \/\/ \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0440\u0430\u0437 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u0438\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0433\u0435\u0442\u0442\u0435\u0440\u044b const createGetters = (_getters, state) => {  const getters = {}  for (const key in _getters) {    getters[key] = (...args) => _getters[key](state, ...args)  }  for (const key in _getters) {    getters[key] = (...args) => _getters[key]({ ...state, getters }, ...args)  }  return getters }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>createSetters()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const createSetters = (_setters, setState) => {  const setters = {}  for (const key in _setters) {    setters[key] = (...args) => {      setState((state) => {        const newState = _setters[key](state, ...args)        return {          ...state,          ...newState        }      })    }  }  return setters }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u0441\u0435\u0442\u0442\u0435\u0440\u044b, \u043d\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430, \u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 (\u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e) \u0441\u0432\u0435\u0436\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043a\u043e\u043b\u0431\u0435\u043a <code>setState()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">setState((state) => {  const newState = setters[key](state, ...args)  return {    ...state,    ...newState  } })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u043f\u043e\u0447\u0435\u043c\u0443 \u0442\u0430\u043a \u0432\u0430\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0435\u0442\u0442\u0435\u0440 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u043a\u043b\u044e\u0447\u043e\u043c (\u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043a\u043b\u044e\u0447\u0430\u043c\u0438), \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u043a\u043b\u044e\u0447\u0430\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0445 \u043a\u043b\u044e\u0447\u0435\u0439 (\u0447\u0430\u0441\u0442\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f) \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u0438 \u0432\u0441\u0435. \u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0445\u0443\u043a <code>useSimpleContext()<\/code> \u0432 \u043d\u0443\u0436\u043d\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { SimpleProvider } from '.\/context'  render(  &lt;React.StrictMode>    &lt;SimpleProvider>      &lt;App \/>    &lt;\/SimpleProvider>  &lt;\/React.StrictMode>,  document.getElementById('root') )  const { simpleState, setSimpleState, setters, getters, actions } = useSimpleContext()<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e, \u043a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u043c\u044b \u0432\u043e\u0432\u0441\u0435 \u043d\u0435 \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u043b\u0438 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434 \u0437\u0430\u043d\u043e\u0432\u043e, \u0430 \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0435\u0433\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043b\u0443\u0447\u0448\u0435. \u041a\u0430\u043a \u044f \u043e\u0442\u043c\u0435\u0447\u0430\u043b \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438, \u0435\u0437\u0434\u0438\u0442\u044c \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0441\u0442\u0430\u043b \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 (\u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u043b\u0435\u0433\u043a\u0430 \u043f\u043e\u0442\u044f\u0436\u0435\u043b\u0435\u043b), \u043d\u043e \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0440\u0430\u0437\u0433\u043e\u043d\u0435. \u0417\u0430\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434 \u0441\u0442\u0430\u043b \u043a\u0440\u0443\u0447\u0435, \u0434\u0430 \u0438 &#171;\u0430\u043f\u0433\u0440\u0435\u0439\u0434\u0438\u0442\u044c&#187; \u0435\u0433\u043e \u0441\u0442\u0430\u043b\u043e \u043b\u0435\u0433\u0447\u0435 ?<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u044d\u0442\u043e \u0432\u0441\u0435, \u0447\u0435\u043c \u044f \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435. \u0411\u0443\u0434\u0443 \u0440\u0430\u0434 \u043b\u044e\u0431\u043e\u0439 \u0444\u043e\u0440\u043c\u0435 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u0432\u044f\u0437\u0438.<\/p>\n<p>  <\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0438 \u0445\u043e\u0440\u043e\u0448\u0435\u0433\u043e \u0434\u043d\u044f!<\/p>\n<p>  <\/p>\n<hr\/>\n<p>  <\/p>\n<blockquote><p><a href=\"https:\/\/t.me\/timewebru\"><b>\u041d\u043e\u0432\u043e\u0441\u0442\u0438, \u043e\u0431\u0437\u043e\u0440\u044b \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432 \u0438 \u043a\u043e\u043d\u043a\u0443\u0440\u0441\u044b \u043e\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b Timeweb.Cloud \u2014 \u0432 \u043d\u0430\u0448\u0435\u043c Telegram-\u043a\u0430\u043d\u0430\u043b\u0435<\/b><\/a> \u21a9<\/p><\/blockquote>\n<p><a href=\"https:\/\/timeweb.cloud\/?i=106909\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/b5\/pj\/of\/b5pjofdoxth14ro-rjsrn7sbmiy.png\" data-src=\"https:\/\/habrastorage.org\/webt\/b5\/pj\/of\/b5pjofdoxth14ro-rjsrn7sbmiy.png\"\/><\/a><\/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\/582320\/\"> https:\/\/habr.com\/ru\/articles\/582320\/<\/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\/4q\/dj\/sj\/4qdjsje-cdcxxlo7dj9n2thrvke.png\" data-src=\"https:\/\/habrastorage.org\/webt\/4q\/dj\/sj\/4qdjsje-cdcxxlo7dj9n2thrvke.png\"\/>  <\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0442, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u043c &#171;\u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0435&#187; \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0430\u043c, \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435, \u043d\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c <code>React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0431\u0435\u0433\u0430\u044f \u0432\u043f\u0435\u0440\u0435\u0434, \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0447\u0443\u0442\u044c \u043c\u0435\u043d\u0435\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c, \u0447\u0435\u043c &#171;\u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435&#187; \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 \u0445\u0443\u043a\u0430 <code>useReducer()<\/code> \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 <code>Context API<\/code> (\u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0438 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u044f\u0434\u0440\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f).<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u043e\u0432, \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043d\u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c <code>React<\/code>, \u0438 \u0432\u043e \u043c\u043d\u043e\u0433\u043e\u043c \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u043b\u0435\u043d\u043e <a href=\"https:\/\/vuex.vuejs.org\/ru\/guide\/\"><code>Vuex<\/code><\/a> \u2014 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c <code>Vue-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u043c \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u0434\u0438\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442\u0441\u044f \u043b\u044e\u0431\u044b\u0435 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f \u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043b\u044e\u0431\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u043a\u0440\u0438\u0442\u0438\u043a\u0430.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u043a\u0430 \u043c\u043d\u0435 \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043b\u043e\u0441\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438\u0441\u043f\u044b\u0442\u0430\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 &#171;\u043f\u043e\u043b\u0435\u0432\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445&#187; (\u044f \u043d\u0430\u043c\u0435\u0440\u0435\u043d \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0443\u0434\u043e\u0431\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435), \u043d\u043e \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043e\u043d\u043e \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043b\u044e\u0431\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438 \u0441\u043e\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u0438 \u0434\u0432\u0443\u0445 \u0432\u0430\u0436\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439:<\/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-406443","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/406443","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=406443"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/406443\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=406443"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=406443"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=406443"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}