{"id":326418,"date":"2021-07-14T09:00:19","date_gmt":"2021-07-14T09:00:19","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=326418"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=326418","title":{"rendered":"Redux Vs Vuex. \u0427\u0430\u0441\u0442\u044c 1"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/py\/cs\/xn\/pycsxnw-4_owrob4sqtc9gqyabi.jpeg\">  <\/p>\n<p>  \u0414\u043e\u0431\u0440\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e <a href=\"https:\/\/redux.js.org\/\"><code>Redux<\/code><\/a> \u0438 <a href=\"https:\/\/next.vuex.vuejs.org\/\"><code>Vuex<\/code><\/a>.<\/p>\n<p>  <\/p>\n<h2 id=\"vvedenie\">\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p><code>Redux<\/code> \u0438 <code>Vuex<\/code> \u2014 \u044d\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \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, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 <a href=\"https:\/\/ru.reactjs.org\/\"><code>React<\/code><\/a> \u0438 <a href=\"https:\/\/vuejs.org\/\"><code>Vue<\/code><\/a>, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u041a\u0430\u0436\u0434\u0430\u044f \u0438\u0437 \u043d\u0438\u0445 \u043f\u043e-\u0441\u0432\u043e\u0435\u043c\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432, \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0443\u044e \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/facebook.github.io\/flux\/\"><code>Flux<\/code><\/a>.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>: Flux-\u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 <em>\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u043c \u0438\u043b\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c<\/em> (global, shared) \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c, \u0442.\u0435. \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0432\u0443\u043c\u044f \u0438 \u0431\u043e\u043b\u0435\u0435 <em>\u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u043c\u0438<\/em> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0410\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u043c\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0439 \u0438\u043b\u0438 \u0441\u0432\u044f\u0437\u0438 \u201c\u043f\u0440\u0435\u0434\u043e\u043a-\u043f\u043e\u0442\u043e\u043c\u043e\u043a\u201d \u0438\u043b\u0438 \u201c\u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c-\u0440\u0435\u0431\u0435\u043d\u043e\u043a\u201d, \u0442.\u0435. \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u0434\u0434\u0435\u0440\u0435\u0432\u044c\u0435\u0432 \u0434\u0435\u0440\u0435\u0432\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u043c \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e (\u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0435\u0432\u0430), \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u043c (local), \u043e\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u044d\u0442\u043e \u043d\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u043c\u0443 (root) \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443.<\/p>\n<p>  <\/p>\n<p>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 <code>Flux<\/code> (\u0432 <code>Redux<\/code>) \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0438\u0441\u0442\u0438\u043d\u044b \u0438\u043b\u0438 \u043c\u0435\u0441\u0442\u0430 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u2014 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 (store);<\/li>\n<li>\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A7%D0%B8%D1%81%D1%82%D0%BE%D1%82%D0%B0_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8\">\u0447\u0438\u0441\u0442\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439<\/a> \u2014 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 (actions);<\/li>\n<li>\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0435 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0430 \u0447\u0435\u0440\u0435\u0437 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 (reducer), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0442\u0438\u043f\u0430 (type) \u0438 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0439 (\u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439) \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 (payload) \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438;<\/li>\n<li>\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 \u0438\u0437 \u0441\u043b\u043e\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f (view), \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u0430 (dispatcher);<\/li>\n<li>\u0432\u044b\u0431\u043e\u0440\u043a\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \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\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 (selectors). \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0430\u0445 \u043a\u0430\u043a \u043e\u0431 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u0445 <code>SELECT<\/code> \u0438\u0437 \u044f\u0437\u044b\u043a\u0430 <code>SQL<\/code><\/li>\n<li>\u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a HTTP- \u0438\u043b\u0438 AJAX-\u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 (thunks).<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a (\u0431\u0435\u0437 \u0443\u0447\u0435\u0442\u0430 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439):<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/gm\/ww\/nq\/gmwwnqmma6rdwtf3ofir3fjrcmy.gif\">  <\/p>\n<p>  \u041d\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u043a\u0442\u043e \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 <code>Flux<\/code> \u043b\u0443\u0447\u0448\u0435, <code>Redux<\/code> \u0438\u043b\u0438 <code>Vuex<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u2014 \u0441\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u0434\u0430\u0447 \u2014 \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 \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\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \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 \u2014 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f;<\/li>\n<li>\u0444\u0438\u043b\u044c\u0442\u0440\u044b: \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \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>\u043a\u043d\u043e\u043f\u043a\u0438 \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, \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 \u0432 &quot;\u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445&quot;, \u0437\u0434\u0435\u0441\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u2014 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c\u0438;<\/li>\n<li>\u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430: \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, \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>\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f: \u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435, \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0437\u0430\u0434\u0430\u0447 \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>\u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c (\u043c\u043d\u043e\u0433\u043e) \u043f\u0440\u043e <a href=\"https:\/\/redux-toolkit.js.org\/\"><code>Redux Toolkit<\/code><\/a> \u0438 (\u043d\u0435\u043c\u043d\u043e\u0433\u043e) \u043f\u0440\u043e <a href=\"https:\/\/react-redux.js.org\/\"><code>React Redux<\/code><\/a>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u2014 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e <a href=\"https:\/\/next.vuex.vuejs.org\/#when-should-i-use-it\"><code>Vuex 4<\/code><\/a>, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e Vue-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u0438\u0437\u043c\u0435\u0440\u0438\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>Redux<\/code> \u0438 <code>Vuex<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u044b \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0445\u043e\u0442\u044f \u0431\u044b \u0441 \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u043d\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0434\u043b\u044f \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430. \u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u044b \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 <a href=\"https:\/\/nodejs.org\/en\/\"><code>Node.js<\/code><\/a>.<\/p>\n<p>  <\/p>\n<p>\u041e \u0441\u0430\u043c\u0438\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u0445 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0443, \u043d\u043e \u043f\u043e\u0447\u0442\u0438 \u043a\u0430\u0436\u0434\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u043a\u043e\u0434\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0441\u043d\u0430\u0431\u0436\u0435\u043d\u0430 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u043c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u043c. \u0412\u043c\u0435\u0441\u0442\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430 \u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u0445, \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u043c\u0435\u0435\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435 (\u043f\u0440\u0430\u0432\u0434\u0430, \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e <code>React<\/code> \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0430, \u043d\u043e \u0442\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435), \u044f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u0434\u0430\u0442\u044c \u0432\u0430\u043c \u0438\u0441\u0447\u0435\u0440\u043f\u044b\u0432\u0430\u044e\u0449\u0435\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e <code>Redux<\/code> \u0438 <code>Vuex<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u0434\u0432\u0430 \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u0434\u0432\u0443\u0445 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0411\u0414 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/github.com\/typicode\/json-server\"><code>JSON Server<\/code><\/a>, \u0430 \u0434\u043b\u044f \u0441\u0442\u0438\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u2014 <a href=\"https:\/\/getbootstrap.com\/\"><code>Bootstrap<\/code><\/a>.<\/p>\n<p>  <\/p>\n<p>\u0412\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/pn\/gj\/kr\/pngjkrasgkocx0tstiqvlvhtw74.png\">  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0434, \u0442\u043e \u0432\u043e\u0442 <a href=\"https:\/\/github.com\/harryheman\/redux-vs-vuex\">\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0414\u0435\u043c\u043e React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/codesandbox.io\/s\/redux-todo-n618x\">\u0437\u0434\u0435\u0441\u044c<\/a>, \u0430 Vue-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u2014 <a href=\"https:\/\/codesandbox.io\/s\/vuex-todo-rsfj5\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0412\u044b \u0433\u043e\u0442\u043e\u0432\u044b? \u0422\u043e\u0433\u0434\u0430 \u0432\u043f\u0435\u0440\u0435\u0434!<\/p>\n<p>  <\/p>\n<h2 id=\"redux-toolkit\"><code>Redux Toolkit<\/code><\/h2>\n<p>  <\/p>\n<p><code>Redux Toolkit<\/code>\u2014 \u044d\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u044e\u0449\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 <code>Redux<\/code>. \u041e\u043d\u0430 \u0431\u044b\u043b\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u0445 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <code>Redux<\/code>:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0441\u043b\u043e\u0436\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430,<\/li>\n<li>\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a,<\/li>\n<li>\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 (boilerplate).<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412 \u0441\u043e\u0441\u0442\u0430\u0432 <code>Redux Toolkit<\/code> \u0432\u0445\u043e\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 (\u0438\u0437 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c):<\/p>\n<p>  <\/p>\n<ul>\n<li><code>configureStore()<\/code>\u2014 \u043e\u0431\u0435\u0440\u0442\u043a\u0430 \u0434\u043b\u044f <code>createStore()<\/code>, \u043c\u0435\u0442\u043e\u0434\u0430 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0438\u0437 <code>Redux<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430. \u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u044b (slice reducers), \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0435 \u0437\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f (\u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0435 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u044b), \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>combineReducers()<\/code> \u0438\u0437 <code>Redux<\/code>. \u041e\u043d \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u043e\u0432 (middlewares) \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442 \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 <a href=\"https:\/\/github.com\/reduxjs\/redux-thunk\"><code>Redux Thunk<\/code><\/a> \u2014 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \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;<\/li>\n<li><code>createSlice()<\/code>\u2014 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440, \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0447\u0430\u0441\u0442\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f (state slice), \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0439 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u044f\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 (action creators);<\/li>\n<li><code>createAsyncThunk()<\/code> \u2014 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439: \u043e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u0438\u043f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0443\u044e \u043f\u0440\u043e\u043c\u0438\u0441, \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 (<code>thunk<\/code>), \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0438\u043f\u044b \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 <code>pending\/fulfilled\/rejected<\/code> \u0432 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0439 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440;<\/li>\n<li><code>createEntityAdapter()<\/code>\u2014 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043d\u0430\u0431\u043e\u0440 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 (reusable) \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u0438 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435;<\/li>\n<li><code>createSelector()<\/code> \u2014 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <a href=\"https:\/\/github.com\/reduxjs\/reselect\"><code>Reselect<\/code><\/a>.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041d\u0435 \u0432\u043e\u043b\u043d\u0443\u0439\u0442\u0435\u0441\u044c, \u043c\u044b \u0441\u043e \u0432\u0441\u0435\u043c \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430, \u0430 \u0437\u0430\u0442\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u0445 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043d\u0430\u0448\u0435\u0433\u043e React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<h3 id=\"configurestore\"><code>configureStore()<\/code><\/h3>\n<p>  <\/p>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>configureStore()<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">{  \/\/ \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u043e\u0432, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c\u044b\u0445 \u0432 \u043e\u0434\u0438\u043d (\u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439, root reducer)  \/\/ \u0441\u0438\u043c\u0432\u043e\u043b `|` \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0418\u041b\u0418, \u0430 \u0441\u0438\u043c\u0432\u043e\u043b `?` \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c (\u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c)  reducer: function | object,  \/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u043e\u0432 (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442)  middleware?: array,  \/\/ \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 `Redux` (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442)  devTools?: boolean | object,  \/\/ \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435  preloadedState: any,  \/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u0443\u0441\u0438\u043b\u0438\u0442\u0435\u043b\u0435\u0439 (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442)  enhancers?: array | function }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u0432 <code>configureStore()<\/code>, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>reducer<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { configureStore } from '@reduxjs\/toolkit' \/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 import rootReducer from '.\/reducer' \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 export const store = configureStore({ reducer: rootReducer })<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u0430\u043c\u0438, \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 <code>Redux<\/code>, \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { configureStore } from '@reduxjs\/toolkit'  \/\/ \u0438\u043c\u043f\u043e\u0440\u0442 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0445 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u043e\u0432 import todoReducer from '.\/todoSlice' import filterReducer from '.\/filterSlice'  \/\/ \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u2014 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 const reducer = {  todos: todoReducer,  filter: filterReducer }  \/\/ \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 const preloadedState = {  todos: [    {      id: '1',      text: 'Eat',      done: true    },    {      id: '2',      text: 'Sleep',      done: false    }  ],  filter: 'all' }  \/\/ \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 export const store = configureStore({  reducer,  devTools: process.env.NODE_ENV === 'development',  preloadedState })<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"createslice\"><code>createSlice()<\/code><\/h3>\n<p>  <\/p>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>createSlice()<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">{  \/\/ \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0447\u0430\u0441\u0442\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u0430 \u0432 \u0442\u0438\u043f\u0430\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439  name: string,  \/\/ \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435  initialState: any,  \/\/ \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u2014 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043a\u043b\u044e\u0447\u0435\u0439 \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0439 \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u0435\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439  reducers: object,  \/\/ \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?: function | object }<\/code><\/pre>\n<p>  <\/p>\n<p><code>createSlice()<\/code> \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u0432\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u0430 \u2014 <code>createAction()<\/code> \u0438 <code>createReducer()<\/code>\u2014 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u0430, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"https:\/\/github.com\/immerjs\/immer\"><code>immer<\/code><\/a> \u0434\u043b\u044f &quot;\u043c\u0443\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f&quot; \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0442.\u0435. \u0434\u043b\u044f \u0435\u0433\u043e \u043f\u0440\u044f\u043c\u043e\u0439 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0430\u043a\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">{  name: string,  reducer: function,  actions,  caseReducers }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u0430\u044f \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>reducers<\/code> \u043c\u0435\u0442\u043e\u0434\u0430 <code>createSlice()<\/code>, \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u044b\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0435 <code>actions<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0439 <code>Redux<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0439 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 &quot;\u0432\u043b\u0430\u0434\u0435\u0435\u0442&quot; \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043a\u0438\u0445 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0442\u0438\u043f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. <code>extraReducers<\/code> \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u044b \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u043f\u043e \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e \u043a \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u0430\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u043e \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { createSlice } from '@reduxjs\/toolkit'  \/\/ \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 const initialState = { value: 0 }  \/\/ \u0447\u0430\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 const counterSlice = createSlice({  name: 'counter',  initialState,  reducers: {    \/\/ \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u043d\u0430 1    increment(state) {      state.value++    },    \/\/ \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u043d\u0430 1    decrement(state) {      state.value--    },    \/\/ \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u043d\u0430 \u0447\u0438\u0441\u043b\u043e, \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 (payload)    incrementByAmount(state, action) {      state.value += action.payload    }  } })  \/\/ \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u0435\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 export const { increment, decrement, incrementByAmount } = counterSlice.actions \/\/ \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u0430 export default counterSlice.reducer<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438, \u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>reducers<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442, \u0430 \u043d\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f. \u0422\u0430\u043a\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0434\u0432\u0430 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430: <code>reducer<\/code> \u0438 <code>prepare<\/code>. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c <code>reducer<\/code> \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c <code>prepare<\/code>\u2014 \u043a\u043e\u043b\u0431\u044d\u043a \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ `nanoid` \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u0441\u043e\u0441\u0442\u0430\u0432 `Redux Toolkit`, \u043c\u0435\u043b\u043e\u0447\u044c, \u0430 \u043f\u0440\u0438\u044f\u0442\u043d\u043e import { createSlice, nanoid } from '@reduxjs\/toolkit'  const toodSlice = createSlice({  name: 'todos',  initialState: [],  reducers: {    \/\/ \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438    \/\/ \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u043a\u0441\u0442 \u0437\u0430\u0434\u0430\u0447\u0438,    \/\/ \u0430 \u043d\u0430\u043c \u0435\u0449\u0435 \u043d\u0443\u0436\u0435\u043d \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440    addTodo: {      \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f      reducer: (state, action) =&gt; {        state.push(action.payload)      },      \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438      prepare: (text) =&gt; {        \/\/ \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c `id`        const id = nanoid(5)        return { payload: { id, text } }      }    }  } })<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u043e \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u043e\u043c \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u043c\u0435\u0442\u043e\u0434 `createAction()` \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u0432 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044f (builder) import { configureStore, createSlice, createAction } from '@reduxjs\/toolkit'  \/\/ \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 const incrementBy = createAction('incrementBy') const decrementBy = createAction('decrementBy')  \/\/ \u0447\u0430\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 const counter = createSlice({  name: 'counter',  initialState: 0,  reducers: {    increment: (state) =&gt; state + 1,    decrement: (state) =&gt; state - 1,    multiply: {      reducer: (state, action) =&gt; state * action.payload,      \/\/ \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u043a\u0430 \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439, \u0435\u0441\u043b\u0438 `value` \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442      prepare: (value) =&gt; ({ payload: value || 2 })    }  },  \/\/ \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u044b  \/\/ \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441  extraReducers: (builder) =&gt; {    builder      .addCase(incrementBy, (state, action) =&gt; state + action.payload)      .addCase(decrementBy, (state, action) =&gt; state - action.payload)  } })  \/\/ \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0439 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f const user = createSlice({  name: 'user',  initialState: { name: 'John', age: 20 },  reducers: {    setName: (state, action) =&gt; {      state.name = action.payload    }  },  \/\/ \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u044b  \/\/ \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441  \/\/ \u043f\u0440\u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u043d\u0430 1,  \/\/ \u0442\u0430\u043a\u0436\u0435 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u043d\u0430 1 \u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f  extraReducers: {    [counter.actions.increment]: (state, action) =&gt; {      state.age += 1    }  } })  \/\/ \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 const store = configureStore({  reducer: {    counter: counter.reducer,    user: user.reducer  } })  \/\/ \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 const { increment, decrement, multiply } = counter.actions \/\/ \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f const { setName } = user.actions  \/\/ \u0434\u043b\u044f \u0440\u0443\u0447\u043d\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 `dispatch()` store.dispatch(increment()) \/\/ { counter: 1, user: {name : 'John', age: 21} } store.dispatch(increment()) \/\/ { counter: 2, user: {name: 'John', age: 22} } store.dispatch(multiply(3)) \/\/ { counter: 6, user: {name: 'John', age: 22} } store.dispatch(multiply()) \/\/ { counter: 12, user: {name: 'John', age: 22} } console.log(`${decrement}`) \/\/ &quot;counter\/decrement&quot; store.dispatch(setUserName('Jane')) \/\/ { counter: 6, user: { name: 'Jane', age: 22} }<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"createasyncthunk\"><code>createAsyncThunk()<\/code><\/h3>\n<p>  <\/p>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>createAsyncThunk()<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u0438\u043f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u043a\u043e\u043b\u0431\u044d\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043f\u0440\u043e\u043c\u0438\u0441 \u0438 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438. \u0422\u0430\u043a\u0436\u0435 \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0442\u0438\u043f\u044b \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u043c\u0443 \u0446\u0438\u043a\u043b\u0443 \u043f\u0440\u043e\u043c\u0438\u0441\u0430, \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c (thunk), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043a\u043e\u043b\u0431\u044d\u043a \u043f\u0440\u043e\u043c\u0438\u0441\u0430 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0432 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u044d\u0442\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u044b. \u0414\u0430, \u043f\u0440\u043e\u0449\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { createAsyncThunk, createSlice } from '@reduxjs\/toolkit' import { userAPI } from '.\/userAPI'  \/\/ \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 `thunk` \/\/ \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0443 const fetchUserById = createAsyncThunk(  'users\/fetchUserById',  async (userId) =&gt; {    const response = await userAPI.fetchById(userId)    return response.data  } )  const userSlice = createSlice({  name: 'users',  initialState: {    entities: [],    loading: 'idle'  },  reducers: {    \/\/ \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u044b  },  extraReducers: {    \/\/ \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430    [fetchUserById.fullfilled]: (state, action) =&gt; {      \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439      state.entities.push(action.payload)    }  } })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 <code>createAsyncThunk()<\/code> \u2014 <code>type<\/code>, <code>payloadCreator<\/code> \u0438 <code>options<\/code>.<\/p>\n<p>  <\/p>\n<ul>\n<li><code>type<\/code> \u2014 \u0441\u0442\u0440\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>type<\/code> \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c <code>users\/requestStatus<\/code> \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0442\u0430\u043a\u0438\u0435 \u0442\u0438\u043f\u044b \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439:<\/li>\n<li><code>pending<\/code>: users\/requestStatus\/pending<\/li>\n<li><code>fulfilled<\/code>: users\/requestStatus\/fulfilled<br \/> \n<ul>\n<li><code>rejected<\/code>: users\/requestStatus\/rejected<\/li>\n<\/ul>\n<\/li>\n<li><code>payloadCreator<\/code> \u2014 \u043a\u043e\u043b\u0431\u044d\u043a, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u043f\u0440\u043e\u043c\u0438\u0441, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u0414\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043b\u0431\u044d\u043a \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u0432\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430:<\/li>\n<li><code>arg<\/code> \u2014 \u043b\u044e\u0431\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0435 <code>thunk<\/code> \u043f\u0440\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0432 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u0430;<\/li>\n<li><code>thunkAPI<\/code> \u2014 \u043e\u0431\u044a\u0435\u043a\u0442, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u0434\u043b\u044f <code>thunk<\/code> \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u043f\u0446\u0438\u0438<\/li>\n<li><code>options<\/code> \u2014 \u043e\u0431\u044a\u0435\u043a\u0442, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430:<\/li>\n<li><code>condition<\/code> \u2014 \u043a\u043e\u043b\u0431\u044d\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f <code>payloadCreator<\/code><\/li>\n<li><code>dispatchConditionRejection<\/code> \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u0438 \u043e\u0442\u043c\u0435\u043d\u0435 <code>thunk<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>condition<\/code>.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e \u0435\u0433\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0443 \u0441 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0437\u0430 \u0440\u0430\u0437:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f `unwrapResult()` \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 `fulfilled` \u0438\u043b\u0438 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 import { createAsyncThunk, createSlice, unwrapResult } from '@reduxjs\/toolkit' import { userAPI } from '.\/userAPI'  const fetchUserById = createAsyncThunk(  'users\/fetchUserById',  \/\/ `getState()` \u2014 \u043c\u0435\u0442\u043e\u0434 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f  \/\/ `requestId` \u2014 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u043f\u0440\u043e\u0441\u0430  async (userId, { getState, requestId }) =&gt; {    \/\/ \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c `id` \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439    const { currentRequestId, loading } = getState().users    \/\/ \u0435\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u041d\u0415 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f `pending` \u0438\u043b\u0438    \/\/ `id` \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u041d\u0415 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 `id` \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430,    \/\/ \u0437\u043d\u0430\u0447\u0438\u0442, \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0435\u0449\u0435 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d    if (loading !== 'pending' || requestId !== currentRequestId) {      return    }    const response = await userAPI.fetchById(userId)    return response.data  } )  \/\/ \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 const userSlice = createSlice({  name: 'users',  initialState: {    entities: [],    loading: 'idle',    currentRequestId: undefined,    error: null  },  reducers: {},  extraReducers: {    \/\/ \u0437\u0430\u043f\u0440\u043e\u0441 \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    [fetchUserById.pending]: (state, action) =&gt; {      if (state.loading === 'idle') {        \/\/ \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438        state.loading = 'pending'        \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u043f\u0440\u043e\u0441\u0430        state.currentRequestId = action.meta.requestId      }    },    \/\/ \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u0443\u0441\u043f\u0435\u0448\u043d\u043e    [fetchUserById.fulfilled]: (state, action) =&gt; {      const { requestId } = action.meta      if (state.loading === 'pending' &amp;&amp; state.currentRequestId === requestId) {        \/\/ \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438        state.loading = 'idle'        \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439        state.entities.push(action.payload)        \/\/ \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430        state.currentRequestId = undefined      }    },    \/\/ \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u043b\u0441\u044f    [fetchUserById.rejected]: (state, action) =&gt; {      if (state.loading === 'pending' &amp;&amp; state.currentRequestId === requestId) {        \/\/ \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438        state.loading = 'idle'        \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e        state.error = action.error        \/\/ \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430        state.currentRequestId = undefined      }    }  } })  \/\/ \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 const UserComponent = () =&gt; {  \/\/ \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438 \u043e\u0448\u0438\u0431\u043a\u0443 \u0438\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439  \/\/ \u043f\u0440\u043e \u0445\u0443\u043a\u0438 `useSelector()` \u0438 `useDispatch()` \u0441\u043c. \u043d\u0438\u0436\u0435  const { user, loading, error } = useSelector((state) =&gt; state.users)  \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440  const dispatch = useDispatch()   const fetchUser = async (userId) =&gt; {    try {      \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f      const result = await dispatch(fetchUserById(userId))      \/\/ \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u043f\u043e\u043b\u0435\u0437\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443      const user = unwrapResult(result)      \/\/ \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u0443\u0441\u043f\u0435\u0445\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438      showToast('success', `\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u044b \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f ${user.name}`)    } catch (err) {      \/\/ \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u043f\u0440\u043e\u0432\u0430\u043b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438      showToast('error', `\u0417\u0430\u043f\u0440\u043e\u0441 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u043e\u0439: ${err.message}`)    }  }   \/\/ \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 }<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"createentityadapter\"><code>createEntityAdapter()<\/code><\/h3>\n<p>  <\/p>\n<p><code>createEntityAdapter()<\/code> \u2014 \u044d\u0442\u043e \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0449\u0430\u044f \u043d\u0430\u0431\u043e\u0440 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u0438 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f <a href=\"https:\/\/ru.wikipedia.org\/wiki\/CRUD\">GRUD-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439<\/a> \u0441 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9D%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0\">\u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u2014 \u044d\u0442\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0431\u043b\u043e\u0433\u0435 \u0442\u0430\u043a\u0438\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c <code>User<\/code>, <code>Post<\/code> \u0438 <code>Comment<\/code>. \u041a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432. \u041a\u0430\u0436\u0434\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440.<\/p>\n<p>  <\/p>\n<p>\u041c\u0435\u0442\u043e\u0434\u044b, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0435 <code>createEntityAdapter()<\/code>, \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u0443\u044e\u0442 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439, \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=\"plaintext\">{  \/\/ \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 `id` \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438 \u0438\u043b\u0438 \u0447\u0438\u0441\u043b\u0430\u043c\u0438  ids: [],  \/\/ \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 (lookup table), \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f `id` \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438  entities: {} }<\/code><\/pre>\n<p>  <\/p>\n<p><code>createEntityAdapter()<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 2 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>selectId<\/code> \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0430\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0430\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u043a\u043e\u0433\u0434\u0430 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043f\u043e\u043b\u0435, \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0449\u0435\u043c\u0441\u044f \u043e\u0442 <code>id<\/code>. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>entity =&gt; entity.id<\/code>;<\/li>\n<li><code>sortComparer<\/code> \u2014 \u043a\u043e\u043b\u0431\u044d\u043a, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439 \u0434\u0432\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 (1, 0 \u0438\u043b\u0438 -1), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 (\u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>Array.sort()<\/code>).<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u043e\u0431\u044a\u0435\u043a\u0442, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u044b, \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b, <code>selectId<\/code>, <code>sortComparer<\/code> \u0438 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u043a\u043d\u0438\u0433\u0430\u043c\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import {  createEntityAdapter,  createSlice,  configureStore } from '@reduxjs\/toolkit'  \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 const bookAdapter = createEntityAdapter({  \/\/ \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043a\u043d\u0438\u0433 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043d\u0435 \u0432 `book.id`, \u0430 \u0432 `book.bookId`  selectId: (book) =&gt; book.bookId,  \/\/ \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c `id` \u043f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c \u043a\u043d\u0438\u0433  sortComparer: (a, b) =&gt; a.title.localeCompare(b.title) })  const bookSlice = createSlice({  name: 'books',  \/\/ \u043c\u0435\u0442\u043e\u0434 `getInitialState()` \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0432\u0438\u0434\u0430 { ids: [], entities: {} }  initialState: bookAdapter.getInitialState(),  reducers: {    \/\/ \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0439 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e    addBook: bookAdapter.addOne,    setBooks(state, action) {      \/\/ \u0438\u043b\u0438 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f (mutation helper)      bookAdapter.setAll(state, action.payload)    }  } })  const store = configureStore({  reducer: {    books: bookSlice.reducer  } })  \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u2014 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 console.log(store.getState().books) \/\/ { ids: [], entities: {} }  \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0430\u0431\u043e\u0440 \u043c\u0435\u043c\u043e\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 const bookSelectors = bookAdapter.getSelectors((state) =&gt; state.books)  \/\/ \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u0445 \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 const allBooks = bookSelector.selectAll(store.getState())<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0431\u043e\u0440 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432 \u0438\u0437 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>addOne<\/code> \u2014 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0435;<\/li>\n<li><code>addMany<\/code> \u2014 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0438\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0444\u043e\u0440\u043c\u044b \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0445;<\/li>\n<li><code>setAll<\/code> \u2014 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0438\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0444\u043e\u0440\u043c\u044b \u0438 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u0438\u043c\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438;<\/li>\n<li><code>removeOne<\/code> \u2014 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0439 <code>id<\/code> \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c, \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0438\u043c\u0435\u0435\u0442\u0441\u044f;<\/li>\n<li><code>removeMany<\/code> \u2014 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 <code>id<\/code> \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438;<\/li>\n<li><code>updateOne<\/code> \u2014 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 <code>id<\/code> \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0438 \u043e\u0431\u044a\u0435\u043a\u0442 <code>changes<\/code> \u0441 \u043e\u0434\u043d\u0438\u043c \u0438\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\u0438, \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u043d\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438;<\/li>\n<li><code>updateMany<\/code> \u2014 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u043d\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439;<\/li>\n<li><code>upsertOne<\/code> \u2014 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c. \u0415\u0441\u043b\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c <code>id<\/code> \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0435\u0435 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u043d\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u043b\u0435\u0439. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0445 \u043f\u043e\u043b\u0435\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f. \u0415\u0441\u043b\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c <code>id<\/code> \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442, \u043e\u043d\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f;<\/li>\n<li><code>upsertMany<\/code> \u2014 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0438\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0444\u043e\u0440\u043c\u044b \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 <code>upsertOne()<\/code> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0438\u043c\u0435\u0435\u0442 \u0442\u0430\u043a\u0443\u044e \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">(state, argument) =&gt; newState<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432\u0438\u0434\u0430 <code>{ids: [], entities: {}}<\/code>, \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0435\u0433\u043e.<\/p>\n<p>  <\/p>\n<p>\u0410\u0434\u0430\u043f\u0442\u0435\u0440 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>getSelectors()<\/code>, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0443\u044e \u043d\u0430\u0431\u043e\u0440 \u043c\u0435\u043c\u043e\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043c\u0435\u044e\u0442 \u0447\u0438\u0442\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>selectIds<\/code> \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 <code>ids<\/code>;<\/li>\n<li><code>selectEntities<\/code> \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 <code>entities<\/code>;<\/li>\n<li><code>selectAll<\/code> \u2014 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0443 <code>ids<\/code> \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0432 \u0442\u043e\u043c \u0436\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0435;<\/li>\n<li><code>selectTotal<\/code> \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0431\u0449\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439;<\/li>\n<li><code>selectById<\/code> \u2014 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 <code>id<\/code>, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0441 \u0434\u0430\u043d\u043d\u044b\u043c <code>id<\/code> \u0438\u043b\u0438 <code>undefined<\/code>.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u043a\u043d\u0438\u0433\u0430\u043c\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import {  createEntityAdapter,  createSlice,  configureStore } from '@reduxjs\/toolkit'  \/\/ \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c `selectId`, \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u043b\u0435\u043c \u0431\u0443\u0434\u0435\u0442 `book.id` const bookAdapter = createEntityAdapter({  sortComparer: (a, b) =&gt; a.title.localeCompare(b.title) })  const bookSlice = createSlice({  name: 'books',  initialState: bookAdapter.getInitialState({    \/\/ \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 \u2014 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438    loading: 'idle'  }),  reducers: {    addBook: bookAdapter.addOne,    loadBooks(state) {      if (state.loading === 'idle') {        state.loading = 'pending'      }    },    setBooks(state, action) {      if (state.loading === 'pending') {        bookAdapter.setAll(state, action.payload)        state.loading = 'idle'      }    },    updateBook: bookAdapter.updateOne  } })  const { addBook, loadBooks, setBooks, updateBook } = bookSlice.actions  const store = configureStore({  reducer: {    books: bookSlice.reducer  } })  \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 console.log(store.getState().books) \/\/ { ids: [], entities: {}, loading: 'idle' }  const { selectIds, selectAll } = bookAdapter.getSelectors(  (state) =&gt; state.books )  store.dispatch(addBook({ id: 'a', title: '\u041f\u0430\u0442\u0442\u0435\u0440\u043d\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f' })) console.log(store.getState().books) \/*  {    ids: [&quot;a&quot;],    entities: {      a: { id: &quot;a&quot;, title: &quot;\u041f\u0430\u0442\u0442\u0435\u0440\u043d\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f&quot;}    },    loading: 'idle'  } *\/  store.dispatch(updateBook({ id: 'a', changes: { title: '\u0413\u0440\u043e\u043a\u0430\u0435\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b' } })) store.dispatch(loadBooks()) console.log(store.getState().books) \/*  {    ids: [&quot;a&quot;],    entities: {      a: { id: &quot;a&quot;, title: &quot;\u0413\u0440\u043e\u043a\u0430\u0435\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b&quot;}},    loading: 'pending'  } *\/  store.dispatch(  setBooks([    { id: 'b', title: '\u0412\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u0442\u0435 JS' },    { id: 'c', title: 'JavaScript. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e' }  ]) )  console.log(booksSelectors.selectIds(store.getState())) \/\/ \u043a\u043d\u0438\u0433\u0430 \u0441 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c &quot;a&quot; \u0431\u044b\u043b\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u0430 \u0438\u0437-\u0437\u0430 \u0432\u044b\u0437\u043e\u0432\u0430 `setAll()` \/\/ \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u043d\u0438\u0433\u0438 \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c, &quot;JavaScript. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e&quot; \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u0434 &quot;\u0412\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u0442\u0435 JS&quot; \/\/ [&quot;c&quot;, &quot;b&quot;]  console.log(booksSelectors.selectAll(store.getState())) \/\/ \u0412\u0441\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0432 \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \/*  [    { id: &quot;c&quot;, title: &quot;JavaScript. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e&quot; },    { id: &quot;b&quot;, title: &quot;\u0412\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u0442\u0435 JS&quot; }  ] *\/<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"createselector\"><code>createSelector()<\/code><\/h3>\n<p>  <\/p>\n<p><code>createSelector()<\/code> \u2014 \u044d\u0442\u043e \u043c\u0435\u0442\u043e\u0434 \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <a href=\"https:\/\/github.com\/reduxjs\/reselect\"><code>Reselect<\/code><\/a> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432. \u041e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043f\u044f\u0442\u0443\u044e \u0438\u043b\u0438 \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440. \u042d\u0442\u043e\u0442 \u043d\u043e\u0432\u044b\u0439 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u0432\u044b\u0431\u043e\u0440\u043a\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<p>  <\/p>\n<p>\u0421\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 const mySelector = createSelector(  \/\/ \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440  (state) =&gt; state.values.value1,  \/\/ \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440  (state) =&gt; state.values.value2,  \/\/ \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430  (value1, value2) =&gt; value1 + value2 )  \/\/ \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 const totalSelector = createSelector(  [(state) =&gt; state.values.value1, (state) =&gt; state.values.value2],  (value1, value2) =&gt; value1 + value2 )<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { createSelector } from '@reduxjs\/toolkit'  \/\/ \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0442\u043e\u0432\u0430\u0440\u043e\u0432 const shopItemsSelector = (state) =&gt; state.shop.items \/\/ \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u043d\u0430\u043b\u043e\u0433\u043e\u0432\u043e\u0439 \u0441\u0442\u0430\u0432\u043a\u0438 (\u0432 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u0430\u0445) const taxPercent = (state) =&gt; state.shop.taxPercent  \/\/ \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u0449\u0435\u0439 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438 \u0442\u043e\u0432\u0430\u0440\u043e\u0432 \u0431\u0435\u0437 \u0443\u0447\u0435\u0442\u0430 \u043d\u0430\u043b\u043e\u0433\u0430 const subtotalSelector = createSelector(shopItemsSelector, (items) =&gt;  items.reduce((subtotal, item) =&gt; subtotal + item.value, 0) )  \/\/ \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u043b\u043e\u0433\u0430 const taxSelector = createSelector(  subtotalSelector,  taxPercentSelector,  (subtotal, taxPercent) =&gt; subtotal * (taxPercent \/ 100) )  \/\/ \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u0449\u0435\u0439 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438 \u0442\u043e\u0432\u0430\u0440\u043e\u0432 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u043d\u0430\u043b\u043e\u0433\u0430 const totalSelector = createSelector(  subtotalSelector,  taxSelector,  (subtotal, tax) =&gt; ({ total: subtotal + tax }) )  \/\/ \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 const state = {  shop: {    taxPercent: 8,    items: [      { name: 'apple', value: 1.2 },      { name: 'orange', value: 0.95 }    ]  } }  console.log(subtotalSelector(state)) \/\/ 2.15 console.log(taxSelector(state)) \/\/ 0.172 console.log(totalSelector(state)) \/\/ { total: 2.322 }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u0442\u0430\u043a, \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0441 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u043c\u0438 <code>Redux Toolkit<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043d\u0430\u0448\u0435\u0433\u043e React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0414\u0430\u043b\u0435\u0435 \u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u043d\u0430 <code>React Redux<\/code>.<\/p>\n<p>  <\/p>\n<h2 id=\"react-redux\"><code>React Redux<\/code><\/h2>\n<p>  <\/p>\n<p><a href=\"https:\/\/react-redux.js.org\/\"><code>React Redux<\/code><\/a> \u2014 \u044d\u0442\u043e &quot;\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043b\u043e\u0439 \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441 Redux&quot;. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u0447\u0438\u0442\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<h3 id=\"api\"><code>API<\/code><\/h3>\n<p>  <\/p>\n<p><strong>\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u0435\u043b\u0430\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043e\u043d \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u0445, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0443\u0440\u043e\u0432\u043d\u044f \u0438\u0445 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import React from 'react' import ReactDOM from 'react-dom' \/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 import { Provider } from 'react-redux' \/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 import store from '.\/store'  import App from '.\/App'  const rootEl = document.getElementById('root') ReactDOM.render(  \/\/ \u0434\u0435\u043b\u0430\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f  &lt;Provider store={store}&gt;    &lt;App \/&gt;  &lt;\/Provider&gt;,  rootEl )<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0425\u0443\u043a\u0438<\/strong><\/p>\n<p>  <\/p>\n<p><code>React Redux<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 2 \u0445\u0443\u043a\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u043c:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>useSelector()<\/code> \u2014 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0438 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u043d\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u2014 \u043b\u044e\u0431\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432\u043b\u0435\u0447\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0430 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430;<\/li>\n<li><code>useDispatch()<\/code> \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440.<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"javascript\">import React from 'react' \/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0445\u0443\u043a\u0438 import { useSelector, useDispatch } from 'react-redux' \/\/ \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 import { decrement, increment, selectCount } from '.\/counterSlice' \/\/ CSS-\u043c\u043e\u0434\u0443\u043b\u044c import styles from '.\/Counter.module.css'  export function Counter() {  \/\/ \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430  const count = useSelector(selectCount)  \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440  const dispatch = useDispatch()   return (    &lt;div&gt;      &lt;div className={styles.row}&gt;        &lt;button          className={styles.button}          aria-label='\u0423\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0430 1'          \/\/ \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u044d\u0442\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438 \u0432 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f `increment()`          onClick={() =&gt; dispatch(increment())}        &gt;          +        &lt;\/button&gt;        {\/* \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 `count` \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043b\u044e\u0431\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 *\/}        &lt;span className={styles.value}&gt;{count}&lt;\/span&gt;        &lt;button          className={styles.button}          aria-label='\u0423\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0430 1'          \/\/ \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u044d\u0442\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438 \u0432 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f `decrement()`          onClick={() =&gt; dispatch(decrement())}        &gt;          -        &lt;\/button&gt;      &lt;\/div&gt;    &lt;\/div&gt;  ) }<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"hranilische-react-prilozheniya\">\u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>  <\/p>\n<h3 id=\"sozdanie-i-nastroyka-proekta\">\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h3>\n<p>  <\/p>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">yarn create react-app redux-todo # \u0438\u043b\u0438 npx create react-app redux-todo<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">cd redux-todo  yarn add @reduxjs\/toolkit axios concurrently json-server react-redux<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/axios\/axios\"><code>axios<\/code><\/a> \u2014 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432;<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/concurrently\"><code>concurrently<\/code><\/a> \u2014 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u0432 <code>package.json<\/code>;<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/json-server\"><code>json-server<\/code><\/a> \u2014 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0423\u0434\u0430\u043b\u044f\u0435\u043c \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u0443\u0436\u043d\u044b\u0435, \u043f\u0440\u0438\u0432\u043e\u0434\u044f \u043f\u0440\u043e\u0435\u043a\u0442 \u043a \u0442\u0430\u043a\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">- public  - index.html - src  - components        - \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b    - List      - Edit.jsx      - \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430      - index.jsx     - \u0441\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u0434\u0430\u0447      - Regular.jsx   - \u043e\u0431\u044b\u0447\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430    - Controls.jsx    - \u043a\u043d\u043e\u043f\u043a\u0438 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f    - Filters.jsx     - \u0444\u0438\u043b\u044c\u0442\u0440\u044b    - Loader.jsx      - \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438    - New.jsx         - \u0444\u043e\u0440\u043c\u0430 \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438    - Stats.jsx       - \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430  - store    - index.jsx       - \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435  - App.jsx  - index.jsx  - ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c <code>bootstrap<\/code> \u0438 <code>bootstrap-icons<\/code> \u0432 <code>public\/index.html<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"html\">&lt;head&gt;  &lt;link    href=&quot;https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@5.0.1\/dist\/css\/bootstrap.min.css&quot;    rel=&quot;stylesheet&quot;    integrity=&quot;sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x&quot;    crossorigin=&quot;anonymous&quot;  \/&gt;  &lt;link    rel=&quot;stylesheet&quot;    href=&quot;https:\/\/cdn.jsdelivr.net\/npm\/bootstrap-icons@1.5.0\/font\/bootstrap-icons.css&quot;  \/&gt; &lt;\/head&gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0444\u0430\u0439\u043b <code>db.json<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f (\u043d\u0430\u0448\u0430 \u0411\u0414):<\/p>\n<p>  <\/p>\n<pre><code class=\"json\">{  &quot;todos&quot;: [    {      &quot;id&quot;: &quot;1&quot;,      &quot;text&quot;: &quot;Eat&quot;,      &quot;done&quot;: true,      &quot;edit&quot;: false    },    {      &quot;id&quot;: &quot;2&quot;,      &quot;text&quot;: &quot;Code&quot;,      &quot;done&quot;: true,      &quot;edit&quot;: false    },    {      &quot;id&quot;: &quot;3&quot;,      &quot;text&quot;: &quot;Sleep&quot;,      &quot;done&quot;: false,      &quot;edit&quot;: false    },    {      &quot;id&quot;: &quot;4&quot;,      &quot;text&quot;: &quot;Repeat&quot;,      &quot;done&quot;: false,      &quot;edit&quot;: false    }  ] }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0438\u043c\u0435\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0442\u0435\u043a\u0441\u0442, \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b <code>scripts<\/code> \u0444\u0430\u0439\u043b\u0430 <code>package.json<\/code> \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438: \u043e\u0434\u043d\u043e\u0433\u043e \u0434\u043b\u044f \u0411\u0414, \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0434\u043b\u044f <code>React<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"json\">&quot;dev&quot;: &quot;concurrently \\&quot;json-server -w db.json -p 5000 -d 1000\\&quot; \\&quot;yarn start\\&quot;&quot;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432 <code>package.json<\/code> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0430 <code>localhost:3000<\/code>):<\/p>\n<p>  <\/p>\n<pre><code class=\"json\">&quot;proxy&quot;: &quot;http:\/\/localhost:5000&quot;<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li>\u0444\u043b\u0430\u0433 <code>-w<\/code> (\u0438\u043b\u0438 <code>--watch<\/code>) \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u0435 \u0437\u0430 \u0444\u0430\u0439\u043b\u043e\u043c <code>db.json<\/code> \u2014 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430;<\/li>\n<li><code>-p<\/code> (\u0438\u043b\u0438 <code>--port<\/code>) \u2014 \u043d\u043e\u043c\u0435\u0440 \u043f\u043e\u0440\u0442\u0430, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0435\u0440 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0440\u0442 <code>3000<\/code>, \u043d\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043d\u044f\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0434\u043b\u044f <code>React<\/code>);<\/li>\n<li><code>-d<\/code> (\u0438\u043b\u0438 <code>--delay<\/code>) \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u0432 1 \u0441\u0435\u043a\u0443\u043d\u0434\u0443 \u043f\u0435\u0440\u0435\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441 (\u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0441\u0445\u043e\u0436\u0435\u0441\u0442\u0438 \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c).<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 \u0432 \u0444\u0430\u0439\u043b <code>scr\/index.jsx<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import axios from 'axios'  axios('http:\/\/localhost:5000\/todos').then((response) =&gt; {  console.log(response.data) })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">yarn dev # \u0438\u043b\u0438 npm run dev<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u0442\u0430\u043a\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">[  { id: &quot;1&quot;, text: &quot;Eat&quot;, done: true, edit: false }  { id: &quot;2&quot;, text: &quot;Code&quot;, done: true, edit: false }  { id: &quot;3&quot;, text: &quot;Sleep&quot;, done: false, edit: false }  { id: &quot;4&quot;, text: &quot;Repeat&quot;, done: false, edit: false } ]<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"proektirovanie-hranilischa\">\u041f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430<\/h3>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043a \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430, \u043f\u043e\u0434\u0443\u043c\u0430\u0435\u043c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043e\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c.<\/p>\n<p>  <\/p>\n<p><strong>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/strong><\/p>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0448\u0438\u0442\u044c: \u0447\u0442\u043e \u0438\u0437 \u0441\u0435\u0431\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c, \u043a\u0440\u043e\u043c\u0435 \u0441\u0430\u043c\u0438\u0445 \u0437\u0430\u0434\u0430\u0447, \u043c\u043e\u0433\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438 \u0442\u0435\u043a\u0441\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430, \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u043b\u0438\u044f\u0442\u044c \u043d\u0430 \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u044b\u0445 \u0437\u0430\u0434\u0430\u0447. \u041d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 <code>all<\/code> \u2014 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0437\u0430\u0434\u0430\u0447.<\/p>\n<p>  <\/p>\n<p><strong>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/strong><\/p>\n<p>  <\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u043e\u043f\u0440\u043e\u0441: \u043a\u0430\u043a\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u043e\u0434\u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u2014 \u043e\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. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0435 <code>setFilter()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0447, \u0442\u043e \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>addTodo()<\/code> \u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438;<\/li>\n<li><code>removeTodo()<\/code> \u2014 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438;<\/li>\n<li><code>updateTodo()<\/code> \u2014 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 (\u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 <code>updateOne()<\/code> \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043b\u044e\u0431\u044b\u0435 (\u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u043d\u044b\u0435) \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f);<\/li>\n<li><code>completeAllTodos()<\/code> \u2014 \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;<\/li>\n<li><code>clearCompletedTodos()<\/code> \u2014 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447.<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438<\/strong><\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u0411\u0414, \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f 2 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f: <code>fetchTodos()<\/code> \u0438 <code>saveTodos()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0436\u0435, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435, \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0437\u0430\u0434\u0430\u0447 \u0438\u043b\u0438 \u043e \u0432\u043e\u0437\u043d\u0438\u043a\u0448\u0435\u0439 \u043e\u0448\u0438\u0431\u043a\u0435 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u2014 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u043f\u0435\u0440\u0435\u0434 \u043e\u0447\u0438\u0441\u0442\u043a\u043e\u0439 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e <code>giveMeSomeTime()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 3 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b 3 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u0430. \u041e\u0434\u043d\u0430\u043a\u043e, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0437\u0430\u0434\u0430\u0447 \u0432 \u0411\u0414, \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 3, \u0430 5 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440\u043e\u0432:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>fetchTodos.pending<\/code> \u2014 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0437\u0430\u0434\u0430\u0447 \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;<\/li>\n<li><code>fetchTodos.fulfilled<\/code> \u2014 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0437\u0430\u0434\u0430\u0447 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430;<\/li>\n<li><code>saveTodos.pending<\/code> \u2014 \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 \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;<\/li>\n<li><code>saveTodos.fulfilled<\/code> \u2014 \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 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430;<\/li>\n<li><code>giveMeSomeTime.fulfilled<\/code> \u2014 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430.<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u0421\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b<\/strong><\/p>\n<p>  <\/p>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430. \u0414\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 <code>selectFilteredTodos()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e <code>selectTodoStats()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u044d\u0442\u043e \u0432\u0441\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430. \u041c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043a \u0435\u0433\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>: \u043e\u0431\u044b\u0447\u043d\u043e, \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>todoSlice.js<\/code>, <code>filterSlice.js<\/code> \u0438 \u0442.\u0434. \u041e\u0434\u043d\u0430\u043a\u043e, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u044b, \u043c\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043c\u0441\u044f \u043e\u0434\u043d\u0438\u043c \u0444\u0430\u0439\u043b\u043e\u043c \u2014 <code>src\/store\/index.js<\/code>.<\/p>\n<p>  <\/p>\n<h3 id=\"realizaciya-hranilischa\">\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430<\/h3>\n<p>  <\/p>\n<p>\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import {  configureStore,  createAsyncThunk,  createEntityAdapter,  createSelector,  createSlice } from '@reduxjs\/toolkit'  import axios from 'axios'<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 \u0434\u043b\u044f \u0430\u0434\u0440\u0435\u0441\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const SERVER_URL = 'http:\/\/localhost:5000\/todos'<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const todoAdapter = createEntityAdapter()<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043d\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:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const initialTodoState = todoAdapter.getInitialState({  \/\/ \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438  status: 'idle',  \/\/ \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435  message: {} })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \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:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const fetchTodos = createAsyncThunk('todos\/fetchTodos', async () =&gt; {  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 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438    return {      todos,      message: { type: 'success', text: 'Todos has been 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 \u043f\u0440\u043e\u0432\u0430\u043b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438    return {      message: { type: 'error', text: 'Something went wrong. Try again later' }    }  } })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 \u0432 \u0411\u0414.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441\u0442\u0430\u043b\u0430 \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439. \u042f \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0441\u0432\u0435\u0441\u0442\u0438 \u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c\u0443 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c\u0441\u044f \u0434\u0432\u0443\u043c\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438: \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 (\u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f) \u0437\u0430\u0434\u0430\u0447 \u0432 \u0411\u0414. \u0412\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e. \u0421 \u043f\u0435\u0440\u0432\u043e\u0439 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e: \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0442\u0432\u0435\u0442. \u041d\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u0437\u0430\u0434\u0430\u0447 \u0432 \u0411\u0414 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0435\u0441\u044f \u0432 \u0411\u0414, \u043e\u0434\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439 (\u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>POST<\/code>);<\/li>\n<li>\u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0435\u0441\u044f \u0432 \u0411\u0414, \u043e\u0434\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439;<\/li>\n<li>\u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u0439 (\u043b\u044e\u0431\u043e\u0439) \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u2014 1 \u0441\u0435\u043a\u0443\u043d\u0434\u0430 (\u0438\u0437-\u0437\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0431\u044b \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043e\u0434\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439, \u0437\u0430\u043f\u0438\u0441\u044c \u043a\u0430\u0436\u0434\u043e\u0439 \u043d\u043e\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f; \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0438\u043c\u0435\u0435\u0442\u0441\u044f 4 \u043d\u043e\u0432\u044b\u0445 \u0437\u0430\u0434\u0430\u0447\u0438: \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0440\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u2014 \u044d\u0442\u043e 1 \u0441\u0435\u043a\u0443\u043d\u0434\u0430, \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u043e\u0432\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u2014 4 \u0441\u0435\u043a\u0443\u043d\u0434\u044b, \u0438\u0442\u043e\u0433\u043e 5 \u0441\u0435\u043a\u0443\u043d\u0434 \u2014 \u043d\u0435\u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0440\u043e\u0441\u043a\u043e\u0448\u044c;<\/li>\n<li>\u0437\u0430\u0434\u0430\u0447\u0438, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0435\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e;<\/li>\n<li>\u0437\u0430\u0434\u0430\u0447\u0438, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0435\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u044b \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e;<\/li>\n<li>\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u043d\u043e\u0432\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438;<\/li>\n<li>\u043c\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u043c \u043a\u0430\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u0431\u0443\u0434\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435: \u0442\u0435\u0445, \u0447\u0442\u043e \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0438\u043b\u0438 \u0442\u0435\u0445, \u0447\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c\u0441\u044f \u043e\u0434\u043d\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u043f\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0443;<\/li>\n<li>\u0437\u0430\u0434\u0430\u0447\u0438, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0435 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440, \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b \u0437\u0430\u0434\u0430\u0447\u0430\u043c, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u043c\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0438 \u0442.\u0434.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u042f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u0441\u0432\u0435\u0441\u0442\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c\u0443. \u0412\u043e\u0442 \u0447\u0442\u043e \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const saveTodos = createAsyncThunk(  'todos\/saveTodos',  async (newTodos) =&gt; {    try {      \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u2014 \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)       \/\/ \u041f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438      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}`         \/\/ \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043d\u0430\u0439\u0442\u0438 \u043e\u0431\u0449\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443        const commonTodo = newTodos.find((_todo) =&gt; _todo.id === todo.id)         \/\/ \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c        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]) =&gt; 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,            \/\/ \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u043c            await axios.put(todoUrl, commonTodo)          }        } else {          \/\/ \u0415\u0441\u043b\u0438 \u043e\u0431\u0449\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442, \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)        }      }       \/\/ \u041f\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        if (!existingTodos.find((_todo) =&gt; _todo.id === todo.id)) {          \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0435 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435          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 has been 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. Try again later'      }    }  } )<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043b\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0432 2 \u0441\u0435\u043a\u0443\u043d\u0434\u044b.<\/p>\n<p>  <\/p>\n<p>\u0418\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u0434\u043b\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0445\u0443\u043a\u0430 <code>useEffect()<\/code> \u0432 <code>App.jsx<\/code>, \u043d\u043e \u043c\u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u0441\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e. \u0418 \u0434\u0430, \u044d\u0442\u043e \u0441\u0432\u043e\u0435\u0433\u043e \u0440\u043e\u0434\u0430 \u043a\u043e\u0441\u0442\u044b\u043b\u044c.<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const giveMeSomeTime = createAsyncThunk(  'todos\/giveMeSomeTime',  async () =&gt;    await new Promise((resolve) =&gt; {      const timerId = setTimeout(() =&gt; {        resolve()        clearTimeout(timerId)      }, 2000)    }) )<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0447\u0430\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">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,  \/\/ \u041e\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) =&gt; {        todo.done = true      })    },    \/\/ \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \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) =&gt; todo.done)        .map((todo) =&gt; todo.id)      todoAdapter.removeMany(state, completedTodoIds)    }  },  \/\/ \u0414\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) =&gt; {    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) =&gt; {        \/\/ \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 }) =&gt; {        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) =&gt; {        \/\/ \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 }) =&gt; {        \/\/ \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 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u0432 2 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d      .addCase(giveMeSomeTime.fulfilled, (state) =&gt; {        \/\/ \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435        state.message = {}      })  } })<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043e\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:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const {  addTodo,  updateTodo,  removeTodo,  completeAllTodos,  clearCompletedTodos } = todoSlice.actions<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0447\u0430\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u041d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \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 \u0444\u0438\u043b\u044c\u0442\u0440\u0430    setFilter(state, action) {      state.status = action.payload    }  } })  \/\/ \u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 export const { setFilter } = filterSlice.actions<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0412\u0441\u0442\u0440\u043e\u0435\u043d\u043d\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 \u043e\u0431\u0449\u0435\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0437\u0430\u0434\u0430\u0447 export const { selectAll, selectTotal } = todoAdapter.getSelectors(  (state) =&gt; state.todos )  \/\/ \u041a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0441\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(  \/\/ \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440  selectAll,  \/\/ \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430  (state) =&gt; state.filter,  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430  (todos, filter) =&gt; {    const { status } = filter    \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c `all`, `active` \u0438\u043b\u0438 `completed`    \/\/ \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442    if (status === 'all') return todos    return status === 'active'      ? todos.filter((todo) =&gt; !todo.done)      : todos.filter((todo) =&gt; 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(  \/\/ \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440  selectAll,  \/\/ \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440  selectTotal,  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430  (todos, total) =&gt; {    \/\/ \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \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 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\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    const completed = todos.filter((todo) =&gt; todo.done).length    const active = total - completed    const percent = total === 0 ? 0 : Math.round((active \/ total) * 100)     return {      total,      completed,      active,      percent    }  } )<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const store = configureStore({  reducer: {    todos: todoSlice.reducer,    filter: filterSlice.reducer  } })<\/code><\/pre>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430:<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">import {  createEntityAdapter,  createSlice,  createSelector,  createAsyncThunk,  configureStore } from '@reduxjs\/toolkit'  import axios from 'axios'  const SERVER_URL = 'http:\/\/localhost:5000\/todos'  const todoAdapter = createEntityAdapter()  const initialTodoState = todoAdapter.getInitialState({  status: 'idle',  message: {} })   export const fetchTodos = createAsyncThunk('todos\/fetchTodos', async () =&gt; {  try {    const { data: todos } = await axios(SERVER_URL)    return {      todos,      message: { type: 'success', text: 'Todos has been loaded' }    }  } catch (err) {    console.error(err.toJSON())    return {      message: { type: 'error', text: 'Something went wrong. Try again later' }    }  } })  export const saveTodos = createAsyncThunk(  'todos\/saveTodos',  async (newTodos) =&gt; {    try {      const { data: existingTodos } = await axios(SERVER_URL)       for (const todo of existingTodos) {        const todoUrl = `${SERVER_URL}\/${todo.id}`         const commonTodo = newTodos.find((_todo) =&gt; _todo.id === todo.id)         if (commonTodo) {          if (            !Object.entries(commonTodo).every(              ([key, value]) =&gt; value === todo[key]            )          ) {            await axios.put(todoUrl, commonTodo)          }        } else {          await axios.delete(todoUrl)        }      }       for (const todo of newTodos) {        if (!existingTodos.find((_todo) =&gt; _todo.id === todo.id)) {          await axios.post(SERVER_URL, todo)        }      }      return { type: 'success', text: 'Todos has been saved' }    } catch (err) {      console.error(err.toJSON())      return {        type: 'error',        text: 'Something went wrong. Try again later'      }    }  } )  export const clearMessage = createAsyncThunk(  'todos\/clearMessage',  async () =&gt;    await new Promise((resolve) =&gt; {      const timerId = setTimeout(() =&gt; {        resolve()        clearTimeout(timerId)      }, 2000)    }) )  const todoSlice = createSlice({\u0451  name: 'todos',  initialState: initialTodoState,  reducers: {    addTodo: todoAdapter.addOne,    updateTodo: todoAdapter.updateOne,    removeTodo: todoAdapter.removeOne,    completeAllTodos(state) {      Object.values(state.entities).forEach((todo) =&gt; {        todo.done = true      })    },    clearCompletedTodos(state) {      const completedTodoIds = Object.values(state.entities)        .filter((todo) =&gt; todo.done)        .map((todo) =&gt; todo.id)      todoAdapter.removeMany(state, completedTodoIds)    }  },  extraReducers: (builder) =&gt; {    builder    .addCase(fetchTodos.pending, (state) =&gt; {      state.status = 'loading'    })    .addCase(fetchTodos.fulfilled, (state, { payload }) =&gt; {      if (payload.todos) {        todoAdapter.setAll(state, payload.todos)      }      state.message = payload.message      state.status = 'idle'    })    .addCase(saveTodos.pending, (state) =&gt; {      state.status = 'loading'    })    .addCase(saveTodos.fulfilled, (state, { payload }) =&gt; {      state.message = payload      state.status = 'idle'    })    .addCase(clearMessage.fulfilled, (state) =&gt; {      state.message = {}    })  } })  export const {  addTodo,  updateTodo,  removeTodo,  completeAllTodos,  clearCompletedTodos } = todoSlice.actions  const initialFilterState = {  status: 'all' }  const filterSlice = createSlice({  name: 'filter',  initialState: initialFilterState,  reducers: {    setFilter(state, action) {      state.status = action.payload    }  } })  export const { setFilter } = filterSlice.actions  export const { selectAll, selectTotal } = todoAdapter.getSelectors(  (state) =&gt; state.todos )  export const selectFilteredTodos = createSelector(  selectAll,  (state) =&gt; state.filter,  (todos, filter) =&gt; {    const { status } = filter    if (status === 'all') return todos    return status === 'active'      ? todos.filter((todo) =&gt; !todo.done)      : todos.filter((todo) =&gt; todo.done)  } )  export const selectTodoStats = createSelector(  selectAll,  selectTotal,  (todos, total) =&gt; {    const completed = todos.filter((todo) =&gt; todo.done).length    const active = total - completed    const percent = total === 0 ? 0 : Math.round((active \/ total) * 100)     return {      total,      completed,      active,      percent    }  } )  export const store = configureStore({  reducer: {    todos: todoSlice.reducer,    filter: filterSlice.reducer  } }) <\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438\u0437 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 \u0432 <code>src\/index.jsx<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import React, { StrictMode } from 'react' import { render } from 'react-dom' \/\/ \u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b import { Provider } from 'react-redux' \/\/ \u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \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 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u043f\u0435\u0440\u0435\u0434 \u043e\u0447\u0438\u0441\u0442\u043a\u043e\u0439 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 import { store, fetchTodos, giveMeSomeTime } from '.\/store'  \/\/ \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f import App from '.\/App'  \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0440\u0435\u0434\u0443\u043a\u0442\u043e\u0440 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 \/\/ \u0438 \u0441\u043b\u0435\u0434\u043e\u043c \u0437\u0430 \u043d\u0435\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0432 2 \u0441\u0435\u043a\u0443\u043d\u0434\u044b store.dispatch(fetchTodos()).then(() =&gt; store.dispatch(giveMeSomeTime()))  render(  &lt;StrictMode&gt;    {\/* \u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u043e\u043f\u0430 `store` *\/}    &lt;Provider store={store}&gt;      &lt;App \/&gt;    &lt;\/Provider&gt;  &lt;\/StrictMode&gt;,  document.getElementById('root') )<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 <code>Redux<\/code> \u0432 \u043b\u0438\u0446\u0435 <code>Redux Toolkit<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 (\u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435, \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u043c <code>Redux<\/code>) \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \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\u044f. \u041d\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 <code>Redux Toolkit<\/code> \u0430\u043f\u043e\u0433\u0435\u0435\u043c \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f Flux-\u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b? \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u043d\u0430 \u044d\u0442\u043e\u0442 \u0441\u0447\u0435\u0442 \u0441\u043a\u0430\u0436\u0435\u0442 <code>Vuex<\/code>, \u043d\u043e \u0443\u0436\u0435 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\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<p><a href=\"https:\/\/timeweb.com\/ru\/?utm_source=habr&amp;utm_medium=banner&amp;utm_campaign=10S&amp;utm_content=low\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/wo\/qf\/6c\/woqf6cweprtwtuq2m7jch92h5wk.png\"><\/a><\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/timeweb\/blog\/566682\/\"> https:\/\/habr.com\/ru\/company\/timeweb\/blog\/566682\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/py\/cs\/xn\/pycsxnw-4_owrob4sqtc9gqyabi.jpeg\">  <\/p>\n<p>  \u0414\u043e\u0431\u0440\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e <a href=\"https:\/\/redux.js.org\/\"><code>Redux<\/code><\/a> \u0438 <a href=\"https:\/\/next.vuex.vuejs.org\/\"><code>Vuex<\/code><\/a>.<\/p>\n<p>  <\/p>\n<h2 id=\"vvedenie\">\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p><code>Redux<\/code> \u0438 <code>Vuex<\/code> \u2014 \u044d\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \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, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 <a href=\"https:\/\/ru.reactjs.org\/\"><code>React<\/code><\/a> \u0438 <a href=\"https:\/\/vuejs.org\/\"><code>Vue<\/code><\/a>, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u041a\u0430\u0436\u0434\u0430\u044f \u0438\u0437 \u043d\u0438\u0445 \u043f\u043e-\u0441\u0432\u043e\u0435\u043c\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432, \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0443\u044e \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/facebook.github.io\/flux\/\"><code>Flux<\/code><\/a>.<\/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-326418","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/326418","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=326418"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/326418\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=326418"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=326418"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=326418"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}