{"id":392109,"date":"2024-06-29T10:13:39","date_gmt":"2024-06-29T10:13:39","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=392109"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=392109","title":{"rendered":"<span>Teaful \u2014 \u043a\u0440\u043e\u0448\u0435\u0447\u043d\u0430\u044f, \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0438 \u043c\u043e\u0449\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 React<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/012\/c0e\/8ad\/012c0e8ade27cbc5c9198d520c5b97bd.png\" width=\"780\" height=\"691\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/012\/c0e\/8ad\/012c0e8ade27cbc5c9198d520c5b97bd.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0421\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u0432 React \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e. \u0418\u0437-\u0437\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0430\u0432\u0442\u043e\u0440 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u043d\u0430 React Context, \u043d\u043e \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430. \u0415\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u044b \u0432\u0441\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0435 \u0441 \u043f\u043e\u043b\u044f\u043c\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. <\/p>\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Teaful, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430\u0437\u044b\u0432\u0430\u043b\u0430\u0441\u044c Fragmented store, \u0440\u0435\u0448\u0430\u0435\u0442 \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u043d\u0430 \u041a\u0414\u041f\u0412. \u0420\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043e Teaful, \u043f\u043e\u043a\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0448 \u043a\u0443\u0440\u0441 \u043f\u043e <a href=\"https:\/\/skillfactory.ru\/python-fullstack-web-developer?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_fpw_251121&amp;utm_term=lead\">Fullstack-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0430 Python<\/a>.<\/p>\n<hr\/>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/844\/a9e\/430\/844a9e43039e982f68cc5fd01ec57987.gif\" alt=\"\u041d\u0435\u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 React Context\" title=\"\u041d\u0435\u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 React Context\" width=\"1098\" height=\"875\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/844\/a9e\/430\/844a9e43039e982f68cc5fd01ec57987.gif\"\/><figcaption>\u041d\u0435\u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 React Context<\/figcaption><\/figure>\n<h2>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 fragmented-store<\/h2>\n<p>Fragmented-store \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u0435 \u043f\u043e\u043b\u0435 store \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0439 store, \u043d\u0435\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0437\u0430\u043d\u043e\u0432\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043b\u0438\u0441\u044c \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u043b\u0435\u0439.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ffe\/62c\/c7d\/ffe62cc7d6d5f687e04d5a2131f63986.gif\" alt=\"Fragmented-store \u0432 React Context\" title=\"Fragmented-store \u0432 React Context\" width=\"880\" height=\"701\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ffe\/62c\/c7d\/ffe62cc7d6d5f687e04d5a2131f63986.gif\"\/><figcaption>Fragmented-store \u0432 React Context<\/figcaption><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e React Context, \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044f store, \u0430 \u044d\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u043e.<\/p>\n<pre><code class=\"javascript\">\/\/ \u274c  Not recommended &lt;UsernameProvider>   &lt;AgeProvider>     {children}   &lt;\/AgeProvider> &lt;\/UsernameProvider><\/code><\/pre>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0435\u0439 \u043c\u043d\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0441\u0432\u043e\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043b\u043e\u0433\u0438\u043a\u0438. \u041e\u0434\u043d\u0430\u043a\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u041f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0438 \u0443\u0434\u043e\u0431\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0430 500 \u0431\u0430\u0439\u0442\u00a0\u2014 fragmented-store.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c Provider<\/h3>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c store \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0432\u043d\u0430\u0447\u0430\u043b\u0435. \u0422\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c React Context:<\/p>\n<pre><code class=\"javascript\">import createStore from \"fragmented-store\";  \/\/ It is advisable to set all the fields. If you don't know the  \/\/ initial value you can set it to undefined or null to be able  \/\/ to consume the values in the same way const { Provider } = createStore({   username: \"Aral\",   age: 31, });  function App() {   return (     &lt;Provider>      {\/* rest *\/}      &lt;\/Provider>   ); } <\/code><\/pre>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043e\u0434\u043d\u043e \u043f\u043e\u043b\u0435<\/h3>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c 2 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u0441 \u043f\u043e\u043b\u0435\u043c store \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u042d\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 <code>useState<\/code> \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 \u0441 \u043d\u0443\u0436\u043d\u044b\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c. \u041d\u043e \u0437\u0434\u0435\u0441\u044c \u043e\u043d\u0438 \u0432\u043c\u0435\u0441\u0442\u0435 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c:<\/p>\n<pre><code class=\"javascript\">import createStore from \"fragmented-store\";  \/\/ We can import hooks with the property name in camelCase. \/\/ username -> useUsername \/\/ age -> useAge const { Provider, useUsername, useAge } = createStore({   username: \"Aral\",   age: 31, });  function App() {   return (     &lt;Provider>      &lt;UsernameComponent \/>      &lt;AgeComponent \/>      &lt;\/Provider>   ); }  \/\/ Consume the \"username\" field function UsernameComponent() {   const [username, setUsername] = useUsername();   return (     &lt;button onClick={() => setUsername(\"AnotherUserName\")}>       Update {username}     &lt;\/button>   ); }  \/\/ Consume the \"age\" field function AgeComponent() {   const [age, setAge] = useAge();   return (     &lt;div>       &lt;div>{age}&lt;\/div>       &lt;button onClick={() => setAge((s) => s + 1)}>Inc age&lt;\/button>     &lt;\/div>   ); }<\/code><\/pre>\n<p>\u041a\u043e\u0433\u0434\u0430 <code>AgeComponent<\/code> \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0435 <code>age<\/code>, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e <code>AgeComponent<\/code>, \u0430 <code>UsernameComponent<\/code> \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0442\u0443 \u0436\u0435 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c store \u0438 \u043d\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u0435\u0441\u044c store<\/h3>\n<p>\u0427\u0442\u043e, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0439? \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0443\u0436\u0435\u043d \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0441\u0440\u0430\u0437\u0443 \u0432\u0435\u0441\u044c store. \u041e\u043d \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043e\u0442\u0440\u0438\u0441\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f:<\/p>\n<pre><code class=\"javascript\">import createStore from \"fragmented-store\";  \/\/ Special hook useStore const { Provider, useStore } = createStore({   username: \"Aral\",   age: 31, });  function App() {   return (     &lt;Provider>      &lt;AllStoreComponent \/>     &lt;\/Provider>   ); }  \/\/ Consume all fields of the store function AllStoreComponent() {   const [store, update] = useStore();    console.log({ store }); \/\/ all store    function onClick() {     update({ age: 32, username: \"Aral Roca\" })   }    return (     &lt;button onClick={onClick}>Modify store&lt;\/button>   ); }<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043b\u044f, \u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0435 \u0441 \u043d\u0438\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u044b, \u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0435 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438 \u2014 \u043d\u0435\u0442:<\/p>\n<pre><code class=\"javascript\">\/\/ It only updates the \"username\" field, other fields won't be updated \/\/ The UsernameComponent is going to be re-rendered while AgeComponent won't :) update({ username: \"Aral Roca\" }) <\/code><\/pre>\n<p>\u041d\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c:<\/p>\n<pre><code class=\"javascript\">update(s => ({ ...s, username: \"Aral\" }))<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u043e\u043b\u0435\u043c <code>username<\/code>\u00a0 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0445\u0443\u043a <code>useUsername<\/code>.<\/p>\n<h2>\u0412\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044f\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h2>\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/github.com\/aralroca\/fragmented-store\">fragmented-store<\/a> \u2014 \u044d\u0442\u043e \u043e\u0434\u0438\u043d <a href=\"https:\/\/github.com\/aralroca\/fragmented-store\/blob\/master\/index.js\">\u043e\u0447\u0435\u043d\u044c <\/a>\u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u0444\u0430\u0439\u043b. \u0412\u044b \u043d\u0435 \u043f\u0438\u0448\u0435\u0442\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u044b React Context \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0440\u0443\u0447\u043d\u0443\u044e. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0432\u0441\u0451, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0445\u0443\u043a\u043e\u0432 \u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">import React, { useState, useContext, createContext } from 'react'  export default function createStore(store = {}) {   const keys = Object.keys(store)   const capitalize = (k) => `${k[0].toUpperCase()}${k.slice(1, k.length)}`    \/\/ storeUtils is the object we'll return with everything   \/\/ (Provider, hooks)   \/\/   \/\/ We initialize it by creating a context for each property and   \/\/ returning a hook to consume the context of each property   const storeUtils = keys.reduce((o, key) => {     const context = createContext(store[key]) \/\/ Property context     const keyCapitalized = capitalize(key)      if (keyCapitalized === 'Store') {       console.error(         'Avoid to use the \"store\" name at the first level, it\\'s reserved for the \"useStore\" hook.'       )     }      return {       ...o,       \/\/ All contexts       contexts: [...(o.contexts || []), { context, key }],       \/\/ Hook to consume the property context       [`use${keyCapitalized}`]: () => useContext(context),     }   }, {})    \/\/ We create the main provider by wrapping all the providers   storeUtils.Provider = ({ children }) => {     const Empty = ({ children }) => children     const Component = storeUtils.contexts       .map(({ context, key }) => ({ children }) => {         const ctx = useState(store[key])         return &lt;context.Provider value={ctx}>{children}&lt;\/context.Provider>       })       .reduce(         (RestProviders, Provider) =>           ({ children }) =>             (               &lt;Provider>                 &lt;RestProviders>{children}&lt;\/RestProviders>               &lt;\/Provider>             ),         Empty       )      return &lt;Component>{children}&lt;\/Component>   }    \/\/ As a bonus, we create the useStore hook to return all the   \/\/ state. Also to return an updater that uses all the created hooks at   \/\/ the same time   storeUtils.useStore = () => {     const state = {}     const updates = {}     keys.forEach((k) => {       const [s, u] = storeUtils[`use${capitalize(k)}`]()       state[k] = s       updates[k] = u     })      function updater(newState) {       const s =         typeof newState === 'function' ? newState(state) : newState || {}       Object.keys(s).forEach((k) => updates[k] &amp;&amp; updates[k](s[k]))     }      return [state, updater]   }    \/\/ Return everything we've generated   return storeUtils }<\/code><\/pre>\n<\/div>\n<\/details>\n<h2>\u0414\u0435\u043c\u043e<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0432\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442,\u044f  \u0441\u043e\u0437\u0434\u0430\u043b \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0443. \u0412 \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b conosle.log, \u0442\u0430\u043a \u0447\u0442\u043e \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f. \u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043d\u043e \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/619fa8006ea11f3bbbaf205b\" data-style=\"\" id=\"619fa8006ea11f3bbbaf205b\" width=\"\"><\/div>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e fragmented-store \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 React Context \u0438 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u0432 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/p>\n<p>\u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438 \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 fragmented-store \u043f\u043e\u043a\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u043b\u0438\u0448\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442\u0441\u044f \u043b\u044e\u0431\u044b\u0435 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043d\u0430 GitHub.<\/p>\n<hr\/>\n<h2>Teaful: \u043a\u0440\u043e\u0448\u0435\u0447\u043d\u043e\u0435, \u043b\u0451\u0433\u043a\u043e\u0435 \u0438 \u043c\u043e\u0449\u043d\u043e\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043d\u0430 React<\/h2>\n<p><a href=\"https:\/\/dev.to\/aralroca\/teaful-tiny-easy-and-powerful-react-state-management-3j9k\"><em>\u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b<\/em><\/a><em> \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438.<\/em><\/p>\n<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u043c\u044b \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043b\u0438 <a href=\"https:\/\/aralroca.com\/blog\/react-fragmented-store\">fragmented-store<\/a> \u2014 \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u043d\u0430 \u043c\u0435\u043d\u044c\u0448\u0435, \u043f\u0440\u043e\u0449\u0435, \u043c\u043e\u0449\u043d\u0435\u0435 \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <strong>Teaful<\/strong>. \u0421 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0430\u0437\u044b\u0432\u0430\u043b\u0430\u0441\u044c \u0442\u0430\u043a:<\/p>\n<ul>\n<li>\n<p><s>Fragmented-store<\/s> -> <s>Fragstore<\/s> -> <strong>Teaful<\/strong><s> <\/s><em>(<\/em><a href=\"https:\/\/github.com\/teafuljs\/teaful\"><em>Teaful GitHub<\/em><\/a><em>)<\/em>.<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6da\/161\/f0e\/6da161f0e3d65453107800319b46f7e5.png\" alt=\"\u041d\u043e\u0432\u044b\u0439 \u043b\u043e\u0433\u043e\u0442\u0438\u043f Teaful\" title=\"\u041d\u043e\u0432\u044b\u0439 \u043b\u043e\u0433\u043e\u0442\u0438\u043f Teaful\" width=\"637\" height=\"634\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6da\/161\/f0e\/6da161f0e3d65453107800319b46f7e5.png\"\/><figcaption>\u041d\u043e\u0432\u044b\u0439 \u043b\u043e\u0433\u043e\u0442\u0438\u043f Teaful<\/figcaption><\/figure>\n<p>\u042d\u0442\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435. \u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e\u0431\u043e \u0432\u0441\u0435\u0445 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u0445.<\/p>\n<h3>\u0427\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u0435\u043d\u044c\u0448\u0435?<\/h3>\n<p>Teaful <strong>\u043c\u0435\u043d\u044c\u0448\u0435 1 \u041a\u0431<\/strong>, \u0442\u0430\u043a \u0447\u0442\u043e \u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043b\u0435\u0433\u0447\u0435:<\/p>\n<pre><code class=\"javascript\">874 B: index.js.gz 791 B: index.js.br 985 B: index.modern.js.gz 888 B: index.modern.js.br 882 B: index.m.js.gz 799 B: index.m.js.br 950 B: index.umd.js.gz 856 B: index.umd.js.br<\/code><\/pre>\n<h3>\u0427\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u0440\u043e\u0449\u0435?<\/h3>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 store \u0438\u043d\u043e\u0433\u0434\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430: \u044d\u043a\u0448\u0435\u043d\u044b, \u0440\u0435\u0434\u044c\u044e\u0441\u0435\u0440\u044b, \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b, connect \u0438 \u0442. \u0434. \u0426\u0435\u043b\u044c Teaful \u2014 \u0431\u044b\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u043b\u0451\u0433\u043a\u043e\u0439 \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438, \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0431\u0435\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432. \u0418 \u0432\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ffa\/dd7\/515\/ffadd75157c8d73722a9ab108e1d27e6.png\" alt=\"Teaful: \u043b\u0451\u0433\u043a\u0430\u044f \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438, \u0431\u0435\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430\" title=\"Teaful: \u043b\u0451\u0433\u043a\u0430\u044f \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438, \u0431\u0435\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430\" width=\"1600\" height=\"1418\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ffa\/dd7\/515\/ffadd75157c8d73722a9ab108e1d27e6.png\"\/><figcaption>Teaful: \u043b\u0451\u0433\u043a\u0430\u044f \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438, \u0431\u0435\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430<\/figcaption><\/figure>\n<h3>\u0427\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u043e\u0449\u043d\u0435\u0435?<\/h3>\n<p>\u041a\u043e\u0434 \u043d\u0430 Teaful \u043b\u0435\u0433\u043a\u043e \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0442\u044c, \u044d\u0442\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0438\u0437\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0442 \u043b\u0438\u0448\u043d\u0438\u0445 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043e\u043a \u0438 \u0443\u043b\u0443\u0447\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0430\u0439\u0442\u0430. \u041a\u043e\u0433\u0434\u0430 \u0432 store \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e, \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u044d\u0442\u0438\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u044b\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/08c\/312\/f17\/08c312f17cd0a0a9612a30bfe92a090e.gif\" alt=\"\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 Teaful\" title=\"\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 Teaful\" width=\"800\" height=\"500\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/08c\/312\/f17\/08c312f17cd0a0a9612a30bfe92a090e.gif\"\/><figcaption>\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 Teaful<\/figcaption><\/figure>\n<h3>\u0414\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430<\/h3>\n<p>\u0412 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 Teaful \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 Redux \u0438\u043b\u0438 Mobx \u0438 \u0434\u0430\u0440\u0438\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c. \u0411\u043e\u043b\u044c\u0448\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0441 \u043d\u0435\u0439 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0442\u044c \u043b\u0435\u0433\u0447\u0435, \u0430 \u0438\u0445 \u043a\u043e\u0434 \u043d\u0435 \u0440\u0430\u0437\u0434\u0443\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<h4>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 store \u043d\u0430 \u043b\u0435\u0442\u0443<\/h4>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 store \u043d\u0430 \u043b\u0435\u0442\u0443:<\/p>\n<pre><code class=\"javascript\">const { useStore } = createStore()  export function Counter() {   const [count, setCount] = useStore.count(0); \/\/ 0 as initial value    return (     &lt;div>       &lt;span>{count}&lt;\/span>       &lt;button onClick={() => setCount(c => c + 1)}>         Increment counter       &lt;\/button>       &lt;button onClick={() => setCount(c => c - 1)}>         Decrement counter       &lt;\/button>     &lt;\/div>   ) }<\/code><\/pre>\n<h4>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0443\u0440\u043e\u0432\u043d\u044f\u043c\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432<\/h4>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043b\u044e\u0431\u044b\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u0432 \u043b\u044e\u0431\u043e\u043c \u043c\u0435\u0441\u0442\u0435 store \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"javascript\">const { useStore } = createStore({   username: \"Aral\",   counters: [     { name: \"My first counter\", counter: { count: 0 } }   ] })  export function Counter({ counterIndex = 0 }) {   const [count, setCount] = useStore.counters[counterIndex].counter.count();    return (     &lt;div>       &lt;span>{count}&lt;\/span>       &lt;button onClick={() => setCount(c => c + 1)}>         Increment counter       &lt;\/button>       &lt;button onClick={() => setCount(c => c - 1)}>         Decrement counter       &lt;\/button>     &lt;\/div>   ) }<\/code><\/pre>\n<h4>\u0421\u0431\u0440\u043e\u0441 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 store \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/h4>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0445\u0443\u043a\u043e\u0432 React \u0442\u0438\u043f\u0430 <code>useState<\/code>, \u0432 Teaful \u0434\u043b\u044f \u0441\u0431\u0440\u043e\u0441\u0430 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0435\u0441\u0442\u044c \u0442\u0440\u0435\u0442\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442:<\/p>\n<pre><code class=\"javascript\">const { useStore } = createStore({ count: 0 })  export function Counter() {   const [count, setCount, resetCounter] = useStore.count();    return (     &lt;div>       &lt;span>{count}&lt;\/span>       &lt;button onClick={() => setCount(c => c + 1)}>         Increment counter       &lt;\/button>       &lt;button onClick={() => setCount(c => c - 1)}>         Decrement counter       &lt;\/button>       &lt;button onClick={resetCounter}>         Reset counter       &lt;\/button>     &lt;\/div>   ) }<\/code><\/pre>\n<p>\u042d\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u0435\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439. \u0412\u043e\u0442 \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u0435\u0441\u044c store:<\/p>\n<pre><code class=\"javascript\">const [store, setStore, resetStore] = useStore(); \/\/ ... resetStore()<\/code><\/pre>\n<h4>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 store<\/h4>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e store \u0438 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0435\u043c \u0445\u0443\u043a\u0438:<\/p>\n<pre><code class=\"javascript\">import createStore from \"teaful\";  export const { useStore: useCart } = createStore({ price: 0, items: [] }); export const { useStore: useCounter } = createStore({ count: 0 });<\/code><\/pre>\n<p>\u0418 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u043c \u0438\u0445 \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u0445:<\/p>\n<pre><code class=\"javascript\">import { useCounter, useCart } from \".\/store\";  function Cart() {   const [price, setPrice] = useCart.price();   \/\/ ... rest }  function Counter() {   const [count, setCount] = useCounter.count();   \/\/ ... rest }<\/code><\/pre>\n<h4>\u041a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f DOM<\/h4>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u043b\u0438 \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f DOM, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0438\u0445 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 <code>getStore<\/code>:<\/p>\n<pre><code class=\"javascript\">import createStore from \"teaful\";  export const { useStore, getStore } = createStore({ count: 0 });  const [, setCount] = getStore.count()  export const incrementCount = () => setCount(c => c + 1) export const decrementCount = () => setCount(c => c - 1)<\/code><\/pre>\n<p>\u0418 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u0445:<\/p>\n<pre><code class=\"javascript\">import { useStore, incrementCount, decrementCount } from \".\/store\";  export function Counter() {   const [count] = useStore.count();    return (     &lt;div>       &lt;span>{count}&lt;\/span>       &lt;button onClick={incrementCount}>         Increment counter       &lt;\/button>       &lt;button onClick={decrementCount}>         Decrement counter       &lt;\/button>     &lt;\/div>   ) }<\/code><\/pre>\n<h4>\u041e\u043f\u0442\u0438\u043c\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f<\/h4>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>onAfterUpdate<\/code> \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0441\u0442\u0438\u0447\u043d\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435. \u0418\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c store \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0432\u044b\u0437\u044b\u0432\u0430\u044f API, \u0430 \u043f\u0440\u0438 \u0441\u0431\u043e\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e:<\/p>\n<pre><code class=\"javascript\">import createStore from \"teaful\";  export const { useStore, getStore } = createStore({ count: 0 }, onAfterUpdate);  function onAfterUpdate({ store, prevStore }) {   if(store.count !== prevStore.count) {     const [count, setCount, resetCount] = getStore.count()      fetch('\/api\/count', { method: 'PATCH', body: count })     .catch(e => setCount(prevStore.count))   } }<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b:<\/p>\n<pre><code class=\"javascript\">import { useStore } from \".\/store\";  export function Counter() {   const [count, setCount] = useStore.count();    return (     &lt;div>       &lt;span>{count}&lt;\/span>       &lt;button onClick={() => setCount(c => c + 1)}>         Increment counter       &lt;\/button>       &lt;button onClick={() => setCount(c => c - 1)}>         Decrement counter       &lt;\/button>     &lt;\/div>   ) }<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u043e\u043f\u0442\u0438\u043c\u0438\u0441\u0442\u0438\u0447\u043d\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u0441\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">const [count, setCount] = useStore.count(0, onAfterUpdate);<\/code><\/pre>\n<h4>\u0412\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 store<\/h4>\n<p>\u0427\u0442\u043e\u0431\u044b <code>cart.price<\/code>\u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u043b \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0437 <code>cart.items<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>onAfterUpdate<\/code>:<\/p>\n<pre><code class=\"javascript\">export const { useStore, getStore } = createStore(   {     cart: {       price: 0,       items: ['apple', 'banana'],     },   },   onAfterUpdate, );  function onAfterUpdate({ store, prevStore }) {   calculatePriceFromItems()   \/\/ ... }  function calculatePriceFromItems() {   const [price, setPrice] = getStore.cart.price();    const [items] = getStore.cart.items();   const calculatedPrice = items.length * 3;    if (price !== calculatedPrice) setPrice(calculatedPrice); }<\/code><\/pre>\n<p>\u0418 \u0441\u043d\u043e\u0432\u0430 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b:<\/p>\n<pre><code class=\"javascript\">import { useStore } from \".\/store\";  export function Counter() {   const [price] = useStore.cart.price();    \/\/ 6\u20ac   return &lt;div>{price}\u20ac&lt;\/div> }<\/code><\/pre>\n<h3>\u0423\u0437\u043d\u0430\u0439\u0442\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043e Teaful<\/h3>\n<p>\u042f \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u0437\u0430\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u0432 <a href=\"https:\/\/github.com\/teafuljs\/teaful\/blob\/0.7.0\/README.md\">README<\/a> \u0438 \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0438 \u0443\u0437\u043d\u0430\u0442\u044c, \u0441 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c. \u0412 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0435\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0435\u043b \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f.<\/p>\n<p>Teaful \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0440\u0430\u043d\u043d\u0435\u0439 \u0441\u0442\u0430\u0434\u0438\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u041a \u0432\u0435\u0440\u0441\u0438\u0438 1.0 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u0442\u0430\u0442\u044c \u0435\u0449\u0451 \u043c\u0435\u043d\u044c\u0448\u0435, \u043b\u0435\u0433\u0447\u0435 \u0438 \u043c\u043e\u0449\u043d\u0435\u0435. \u0421\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u0440\u0430\u0441\u0442\u0451\u0442, \u043c\u044b \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u043c \u043b\u044e\u0431\u044b\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u042f \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e \u0432\u0441\u0435\u0445, \u043a\u0442\u043e \u0432\u043d\u0451\u0441 \u0441\u0432\u043e\u0439 \u0432\u043a\u043b\u0430\u0434 \u0432 \u043a\u043e\u0434 Teaful.<\/p>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 React \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430 \u043d\u0430\u0448\u0438\u0445 \u043a\u0443\u0440\u0441\u0430\u0445:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/970\/531\/d16\/970531d166a5177682a7c6761fa2be4c.png\" width=\"1000\" height=\"269\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/970\/531\/d16\/970531d166a5177682a7c6761fa2be4c.png\"\/><figcaption><\/figcaption><\/figure>\n<p><a href=\"https:\/\/skillfactory.ru\/catalogue?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=sf_allcourses_251121&amp;utm_term=conc\">\u0423\u0437\u043d\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438<\/a> \u0430\u043a\u0446\u0438\u0438.<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/python-fullstack-web-developer?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_fpw_251121&amp;utm_term=conc\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f Fullstack-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043d\u0430 Python (15 \u043c\u0435\u0441\u044f\u0446\u0435\u0432)<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/frontend-razrabotchik?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_fr_251121&amp;utm_term=conc\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f Frontend-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a (7 \u043c\u0435\u0441\u044f\u0446\u0435\u0432)<\/a><\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u0414\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u0438 \u0438 \u043a\u0443\u0440\u0441\u044b<\/summary>\n<div class=\"spoiler__content\">\n<p><strong>Data Science \u0438 Machine Learning<\/strong><\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/data-scientist-pro?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=data-science_dspr_251121&amp;utm_term=cat\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f Data Scientist<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/data-analyst-pro?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=analytics_dapr_251121&amp;utm_term=cat\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f Data Analyst<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/matematika-dlya-data-science#syllabus?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=data-science_mat_251121&amp;utm_term=cat\">\u041a\u0443\u0440\u0441 \u00ab\u041c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0430 \u0434\u043b\u044f Data Science\u00bb<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/matematika-i-machine-learning-dlya-data-science?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=data-science_matml_251121&amp;utm_term=cat\">\u041a\u0443\u0440\u0441 \u00ab\u041c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0430 \u0438 Machine Learning \u0434\u043b\u044f Data Science\u00bb<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/data-engineer?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=data-science_dea_251121&amp;utm_term=cat\">\u041a\u0443\u0440\u0441 \u043f\u043e Data Engineering<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/machine-learning-i-deep-learning?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=data-science_mldl_251121&amp;utm_term=cat\">\u041a\u0443\u0440\u0441 \u00abMachine Learning \u0438 Deep Learning\u00bb<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/machine-learning?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=data-science_ml_251121&amp;utm_term=cat\">\u041a\u0443\u0440\u0441 \u043f\u043e Machine Learning<\/a><\/p>\n<\/li>\n<\/ul>\n<p><strong>Python, \u0432\u0435\u0431-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/strong><\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/python-fullstack-web-developer?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_fpw_251121&amp;utm_term=cat\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f Fullstack-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043d\u0430 Python<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/python-for-web-developers?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_pws_251121&amp;utm_term=cat\">\u041a\u0443\u0440\u0441 \u00abPython \u0434\u043b\u044f \u0432\u0435\u0431-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438\u00bb<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/frontend-razrabotchik?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_fr_251121&amp;utm_term=cat\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f Frontend-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/webdev?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_webdev_251121&amp;utm_term=cat\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f \u0412\u0435\u0431-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/a><\/p>\n<\/li>\n<\/ul>\n<p><strong>\u041c\u043e\u0431\u0438\u043b\u044c\u043d\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/strong><\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/ios-razrabotchik-s-nulya?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_ios_251121&amp;utm_term=cat\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f iOS-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/android-razrabotchik?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_andr_251121&amp;utm_term=cat\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f Android-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/a><\/p>\n<\/li>\n<\/ul>\n<p><strong>Java \u0438 C#<\/strong><\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/java-razrabotchik?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_java_251121&amp;utm_term=cat\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f Java-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/java-qa-engineer-testirovshik-po?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_qaja_251121&amp;utm_term=cat\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f QA-\u0438\u043d\u0436\u0435\u043d\u0435\u0440 \u043d\u0430 JAVA<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/c-sharp-razrabotchik?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_cdev_251121&amp;utm_term=cat\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f C#-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/game-razrabotchik-na-unity-i-c-sharp?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_gamedev_251121&amp;utm_term=cat\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0433\u0440 \u043d\u0430 Unity<\/a><\/p>\n<\/li>\n<\/ul>\n<p><strong>\u041e\u0442 \u043e\u0441\u043d\u043e\u0432 \u2014 \u0432 \u0433\u043b\u0443\u0431\u0438\u043d\u0443<\/strong><\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/algoritmy-i-struktury-dannyh?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_algo_251121&amp;utm_term=cat\">\u041a\u0443\u0440\u0441 \u00ab\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445\u00bb<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/c-plus-plus-razrabotchik?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_cplus_251121&amp;utm_term=cat\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f C++ \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/cyber-security-etichnij-haker?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_hacker_251121&amp;utm_term=cat\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f \u042d\u0442\u0438\u0447\u043d\u044b\u0439 \u0445\u0430\u043a\u0435\u0440<\/a><\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0410 \u0442\u0430\u043a\u0436\u0435<\/strong><\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/devops-ingineer?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_devops_251121&amp;utm_term=cat\">\u041a\u0443\u0440\u0441 \u043f\u043e DevOps<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/skillfactory.ru\/catalogue?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=sf_allcourses_251121&amp;utm_term=conc\">\u0412\u0441\u0435 \u043a\u0443\u0440\u0441\u044b<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/591605\/\"> https:\/\/habr.com\/ru\/articles\/591605\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0421\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u0432 React \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e. \u0418\u0437-\u0437\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0430\u0432\u0442\u043e\u0440 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u043d\u0430 React Context, \u043d\u043e \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430. \u0415\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u044b \u0432\u0441\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0435 \u0441 \u043f\u043e\u043b\u044f\u043c\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. <\/p>\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Teaful, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430\u0437\u044b\u0432\u0430\u043b\u0430\u0441\u044c Fragmented store, \u0440\u0435\u0448\u0430\u0435\u0442 \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u043d\u0430 \u041a\u0414\u041f\u0412. \u0420\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043e Teaful, \u043f\u043e\u043a\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0448 \u043a\u0443\u0440\u0441 \u043f\u043e <a href=\"https:\/\/skillfactory.ru\/python-fullstack-web-developer?utm_source=habr&amp;utm_medium=habr&amp;utm_campaign=article&amp;utm_content=coding_fpw_251121&amp;utm_term=lead\">Fullstack-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0430 Python<\/a>.<\/p>\n<hr\/>\n<figure class=\"full-width\"><figcaption>\u041d\u0435\u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 React Context<\/figcaption><\/figure>\n<h2>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 fragmented-store<\/h2>\n<p>Fragmented-store \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u0435 \u043f\u043e\u043b\u0435 store \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0439 store, \u043d\u0435\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0437\u0430\u043d\u043e\u0432\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043b\u0438\u0441\u044c \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u043b\u0435\u0439.<\/p>\n<figure class=\"full-width\"><figcaption>Fragmented-store \u0432 React Context<\/figcaption><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e React Context, \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044f store, \u0430 \u044d\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u043e.<\/p>\n<pre><code class=\"javascript\">\/\/ \u274c  Not recommended &lt;UsernameProvider>   &lt;AgeProvider>     {children}   &lt;\/AgeProvider> &lt;\/UsernameProvider><\/code><\/pre>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0435\u0439 \u043c\u043d\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0441\u0432\u043e\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043b\u043e\u0433\u0438\u043a\u0438. \u041e\u0434\u043d\u0430\u043a\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u041f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0438 \u0443\u0434\u043e\u0431\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0430 500 \u0431\u0430\u0439\u0442\u00a0\u2014 fragmented-store.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c Provider<\/h3>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c store \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0432\u043d\u0430\u0447\u0430\u043b\u0435. \u0422\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c React Context:<\/p>\n<pre><code class=\"javascript\">import createStore from \"fragmented-store\";  \/\/ It is advisable to set all the fields. If you don't know the  \/\/ initial value you can set it to undefined or null to be able  \/\/ to consume the values in the same way const { Provider } = createStore({   username: \"Aral\",   age: 31, });  function App() {   return (     &lt;Provider>      {\/* rest *\/}      &lt;\/Provider>   ); } <\/code><\/pre>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043e\u0434\u043d\u043e \u043f\u043e\u043b\u0435<\/h3>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c 2 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u0441 \u043f\u043e\u043b\u0435\u043c store \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u042d\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 <code>useState<\/code> \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 \u0441 \u043d\u0443\u0436\u043d\u044b\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c. \u041d\u043e \u0437\u0434\u0435\u0441\u044c \u043e\u043d\u0438 \u0432\u043c\u0435\u0441\u0442\u0435 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c:<\/p>\n<pre><code class=\"javascript\">import createStore from \"fragmented-store\";  \/\/ We can import hooks with the property name in camelCase. \/\/ username -> useUsername \/\/ age -> useAge const { Provider, useUsername, useAge } = createStore({   username: \"Aral\",   age: 31, });  function App() {   return (     &lt;Provider>      &lt;UsernameComponent \/>      &lt;AgeComponent \/>      &lt;\/Provider>   ); }  \/\/ Consume the \"username\" field function UsernameComponent() {   const [username, setUsername] = useUsername();   return (     &lt;button onClick={() => setUsername(\"AnotherUserName\")}>       Update {username}     &lt;\/button>   ); }  \/\/ Consume the \"age\" field function AgeComponent() {   const [age, setAge] = useAge();   return (     &lt;div>       &lt;div>{age}&lt;\/div>       &lt;button onClick={() => setAge((s) => s + 1)}>Inc age&lt;\/button>     &lt;\/div>   ); }<\/code><\/pre>\n<p>\u041a\u043e\u0433\u0434\u0430 <code>AgeComponent<\/code> \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0435 <code>age<\/code>, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e <code>AgeComponent<\/code>, \u0430 <code>UsernameComponent<\/code> \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0442\u0443 \u0436\u0435 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c store \u0438 \u043d\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u0435\u0441\u044c store<\/h3>\n<p>\u0427\u0442\u043e, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0439? \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0443\u0436\u0435\u043d \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0441\u0440\u0430\u0437\u0443 \u0432\u0435\u0441\u044c store. \u041e\u043d \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043e\u0442\u0440\u0438\u0441\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f:<\/p>\n<pre><code class=\"javascript\">import createStore from \"fragmented-store\";  \/\/ Special hook useStore const { Provider, useStore } = createStore({   username: \"Aral\",   age: 31, });  function App() {   return (     &lt;Provider>      &lt;AllStoreComponent \/>     &lt;\/Provider>   ); }  \/\/ Consume all fields of the store function AllStoreComponent() {   const [store, update] = useStore();    console.log({ store }); \/\/ all store    function onClick() {     update({ age: 32, username: \"Aral Roca\" })   }    return (     &lt;button onClick={onClick}>Modify store&lt;\/button>   ); }<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043b\u044f, \u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0435 \u0441 \u043d\u0438\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u044b, \u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0435 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438 \u2014 \u043d\u0435\u0442:<\/p>\n<pre><code class=\"javascript\">\/\/ It only updates the \"username\" field, other fields won't be updated \/\/ The UsernameComponent is going to be re-rendered while AgeComponent won't :) update({ username: \"Aral Roca\" }) <\/code><\/pre>\n<p>\u041d\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c:<\/p>\n<pre><code class=\"javascript\">update(s => ({ ...s, username: \"Aral\" }))<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u043e\u043b\u0435\u043c <code>username<\/code>\u00a0 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0445\u0443\u043a <code>useUsername<\/code>.<\/p>\n<h2>\u0412\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044f\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h2>\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/github.com\/aralroca\/fragmented-store\">fragmented-store<\/a> \u2014 \u044d\u0442\u043e \u043e\u0434\u0438\u043d <a href=\"https:\/\/github.com\/aralroca\/fragmented-store\/blob\/master\/index.js\">\u043e\u0447\u0435\u043d\u044c <\/a>\u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u0444\u0430\u0439\u043b. \u0412\u044b \u043d\u0435 \u043f\u0438\u0448\u0435\u0442\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u044b React Context \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0440\u0443\u0447\u043d\u0443\u044e. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0432\u0441\u0451, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0445\u0443\u043a\u043e\u0432 \u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">import React, { useState, useContext, createContext } from 'react'  export default function createStore(store = {}) {   const keys = Object.keys(store)   const capitalize = (k) => `${k[0].toUpperCase()}${k.slice(1, k.length)}`    \/\/ storeUtils is the object we'll return with everything   \/\/ (Provider, hooks)   \/\/   \/\/ We initialize it by creating a context for each property and   \/\/ returning a hook to consume the context of each property   const storeUtils = keys.reduce((o, key) => {     const context = createContext(store[key]) \/\/ Property context     const keyCapitalized = capitalize(key)      if (keyCapitalized === 'Store') {       console.error(         'Avoid to use the \"store\" name at the first level, it\\'s reserved for the \"useStore\" hook.'       )     }      return {       ...o,       \/\/ All contexts       contexts: [...(o.contexts || []), { context, key }],       \/\/ Hook to consume the property context       [`use${keyCapitalized}`]: () => useContext(context),     }   }, {})    \/\/ We create the main provider by wrapping all the providers   storeUtils.Provider = ({ children }) => {     const Empty = ({ children }) => children     const Component = storeUtils.contexts       .map(({ context, key }) => ({ children }) => {         const ctx = useState(store[key])         return &lt;context.Provider value={ctx}>{children}&lt;\/context.Provider>       })       .reduce(         (RestProviders, Provider) =>           ({ children }) =>             (               &lt;Provider>                 &lt;RestProviders>{children}&lt;\/RestProviders>               &lt;\/Provider>             ),         Empty       )      return &lt;Component>{children}&lt;\/Component>   }    \/\/ As a bonus, we create the useStore hook to return all the   \/\/ state. Also to return an updater that uses all the created hooks at   \/\/ the same time   storeUtils.useStore = () => {     const state = {}     const updates = {}     keys.forEach((k) => {       const [s, u] = storeUtils[`use${capitalize(k)}`]()       state[k] = s       updates[k] = u     })      function updater(newState) {       const s =         typeof newState === 'function' ? newState(state) : newState || {}       Object.keys(s).forEach((k) => updates[k] &amp;&amp; updates[k](s[k]))     }      return [state, updater]   }    \/\/ Return everything we've generated   return storeUtils }<\/code><\/pre>\n<\/div>\n<\/details>\n<h2>\u0414\u0435\u043c\u043e<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0432\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442,\u044f  \u0441\u043e\u0437\u0434\u0430\u043b \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0443. \u0412 \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b conosle.log, \u0442\u0430\u043a \u0447\u0442\u043e \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f. \u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043d\u043e \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/619fa8006ea11f3bbbaf205b\" data-style=\"\" id=\"619fa8006ea11f3bbbaf205b\" width=\"\"><\/div>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e fragmented-store \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 React Context \u0438 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u0432 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/p>\n<p>\u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438 \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 fragmented-store \u043f\u043e\u043a\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u043b\u0438\u0448\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442\u0441\u044f \u043b\u044e\u0431\u044b\u0435 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043d\u0430 GitHub.<\/p>\n<hr\/>\n<h2>Teaful: \u043a\u0440\u043e\u0448\u0435\u0447\u043d\u043e\u0435, \u043b\u0451\u0433\u043a\u043e\u0435 \u0438 \u043c\u043e\u0449\u043d\u043e\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043d\u0430 React<\/h2>\n<p><a href=\"https:\/\/dev.to\/aralroca\/teaful-tiny-easy-and-powerful-react-state-management-3j9k\"><em>\u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b<\/em><\/a><em> \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438.<\/em><\/p>\n<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u043c\u044b \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043b\u0438 <a href=\"https:\/\/aralroca.com\/blog\/react-fragmented-store\">fragmented-store<\/a> \u2014 \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u043d\u0430 \u043c\u0435\u043d\u044c\u0448\u0435, \u043f\u0440\u043e\u0449\u0435, \u043c\u043e\u0449\u043d\u0435\u0435 \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <strong>Teaful<\/strong>. \u0421 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0430\u0437\u044b\u0432\u0430\u043b\u0430\u0441\u044c \u0442\u0430\u043a:<\/p>\n<ul>\n<li>\n<p><s>Fragmented-store<\/s> -> <s>Fragstore<\/s> -> <strong>Teaful<\/strong><s> <\/s><em>(<\/em><a href=\"https:\/\/github.com\/teafuljs\/teaful\"><em>Teaful GitHub<\/em><\/a><em>)<\/em>.<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><figcaption>\u041d\u043e\u0432\u044b\u0439 \u043b\u043e\u0433\u043e\u0442\u0438\u043f Teaful<\/figcaption><\/figure>\n<p>\u042d\u0442\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435. \u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e\u0431\u043e \u0432\u0441\u0435\u0445 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u0445.<\/p>\n<h3>\u0427\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u0435\u043d\u044c\u0448\u0435?<\/h3>\n<p>Teaful <strong>\u043c\u0435\u043d\u044c\u0448\u0435 1 \u041a\u0431<\/strong>, \u0442\u0430\u043a \u0447\u0442\u043e \u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043b\u0435\u0433\u0447\u0435:<\/p>\n<pre><code class=\"javascript\">874 B: index.js.gz 791 B: index.js.br 985 B: index.modern.js.gz 888 B: index.modern.js.br 882 B: index.m.js.gz 799 B: index.m.js.br 950 B: index.umd.js.gz 856 B: index.umd.js.br<\/code><\/pre>\n<h3>\u0427\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u0440\u043e\u0449\u0435?<\/h3>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 store \u0438\u043d\u043e\u0433\u0434\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430: \u044d\u043a\u0448\u0435\u043d\u044b, \u0440\u0435\u0434\u044c\u044e\u0441\u0435\u0440\u044b, \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b, connect \u0438 \u0442. \u0434. \u0426\u0435\u043b\u044c Teaful \u2014 \u0431\u044b\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u043b\u0451\u0433\u043a\u043e\u0439 \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438, \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0431\u0435\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432. \u0418 \u0432\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"full-width\"><figcaption>Teaful: \u043b\u0451\u0433\u043a\u0430\u044f \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438, \u0431\u0435\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430<\/figcaption><\/figure>\n<h3>\u0427\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u043e\u0449\u043d\u0435\u0435?<\/h3>\n<p>\u041a\u043e\u0434 \u043d\u0430 Teaful \u043b\u0435\u0433\u043a\u043e \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0442\u044c, \u044d\u0442\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0438\u0437\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0442 \u043b\u0438\u0448\u043d\u0438\u0445 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043e\u043a \u0438 \u0443\u043b\u0443\u0447\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0430\u0439\u0442\u0430. \u041a\u043e\u0433\u0434\u0430 \u0432 store \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e, \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u044d\u0442\u0438\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u044b\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c:<\/p>\n<figure class=\"full-width\"><figcaption>\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 Teaful<\/figcaption><\/figure>\n<h3>\u0414\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430<\/h3>\n<p>\u0412 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 Teaful \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 Redux \u0438\u043b\u0438 Mobx \u0438 \u0434\u0430\u0440\u0438\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c. \u0411\u043e\u043b\u044c\u0448\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0441 \u043d\u0435\u0439 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0442\u044c \u043b\u0435\u0433\u0447\u0435, \u0430 \u0438\u0445 \u043a\u043e\u0434 \u043d\u0435 \u0440\u0430\u0437\u0434\u0443\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<h4>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 store \u043d\u0430 \u043b\u0435\u0442\u0443<\/h4>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 store \u043d\u0430 \u043b\u0435\u0442\u0443:<\/p>\n<pre><code class=\"javascript\">const { useStore } = createStore()  export function Counter() {   const [count, setCount] = useStore.count(0); \/\/ 0 as initial value    return (     &lt;div>       &lt;span>{count}&lt;\/span>       &lt;button onClick={() => setCount(c => c + 1)}>         Increment counter       &lt;\/button>       &lt;button onClick={() => setCount(c => c - 1)}>         Decrement counter       &lt;\/button>     &lt;\/div>   ) }<\/code><\/pre>\n<h4>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0443\u0440\u043e\u0432\u043d\u044f\u043c\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432<\/h4>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043b\u044e\u0431\u044b\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u0432 \u043b\u044e\u0431\u043e\u043c \u043c\u0435\u0441\u0442\u0435 store \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"javascript\">const { useStore } = createStore({   username: \"Aral\",   counters: [     { name: \"My first counter\", counter: { count: 0 } }   ] })  export function Counter({ counterIndex = 0 }) {   const [count, setCount] = useStore.counters[counterIndex].counter.count();    return (     &lt;div>       &lt;span>{count}&lt;\/span>       &lt;button onClick={() => setCount(c => c + 1)}>         Increment counter       &lt;\/button>       &lt;button onClick={() => setCount(c => c - 1)}>         Decrement counter       &lt;\/button>     &lt;\/div>   ) }<\/code><\/pre>\n<h4>\u0421\u0431\u0440\u043e\u0441 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 store \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/h4>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0445\u0443\u043a\u043e\u0432 React \u0442\u0438\u043f\u0430 <code>useState<\/code>, \u0432 Teaful \u0434\u043b\u044f \u0441\u0431\u0440\u043e\u0441\u0430 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0435\u0441\u0442\u044c \u0442\u0440\u0435\u0442\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442:<\/p>\n<pre><code class=\"javascript\">const { useStore } = createStore({ count: 0 })  export<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-392109","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/392109","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=392109"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/392109\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=392109"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=392109"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=392109"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}