{"componentChunkName":"component---src-templates-content-template-js","path":"/en/part6/complex_state_fetch_testing","result":{"data":{"markdownRemark":{"html":"<div class=\"content\">\n<p>Let's continue extending the Zustand version of the notes application.</p>\n<p>To make development easier, let's change the initial state so that it already contains a few notes:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">const</span> initialNotes <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token literal-property property\">id</span><span class=\"token operator\">:</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token literal-property property\">content</span><span class=\"token operator\">:</span> <span class=\"token string\">'Zustand is less complex than Redux'</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token literal-property property\">id</span><span class=\"token operator\">:</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token literal-property property\">content</span><span class=\"token operator\">:</span> <span class=\"token string\">'React app benefits from custom hooks'</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token literal-property property\">id</span><span class=\"token operator\">:</span> <span class=\"token number\">3</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token literal-property property\">content</span><span class=\"token operator\">:</span> <span class=\"token string\">'Remember to sleep well'</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">]</span></span><span class=\"gatsby-highlight-code-line\"></span><span class=\"gatsby-highlight-code-line\"></span>\n<span class=\"token keyword\">const</span> useNoteStore <span class=\"token operator\">=</span> <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token keyword\">set</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> initialNotes<span class=\"token punctuation\">,</span>\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h3>More complex state</h3>\n<p>Let's implement filtering of the notes displayed in the application, allowing the visible notes to be restricted. The filter is implemented using <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio\">radio buttons</a>:</p>\n<picture><img src=\"/static/a10eaa11ed554b28b204fd0840d62e00/5a190/u1.png\" alt=\"At the top of the page a form for adding a note (input field and an add button). Below that radio button selection for which notes to show, options: all, important and nonimportant. Below these all notes are rendered, with the text important next to notes marked as important.\" srcset=\"/static/a10eaa11ed554b28b204fd0840d62e00/772e8/u1.png 200w,\n/static/a10eaa11ed554b28b204fd0840d62e00/e17e5/u1.png 400w,\n/static/a10eaa11ed554b28b204fd0840d62e00/5a190/u1.png 800w,\n/static/a10eaa11ed554b28b204fd0840d62e00/c1b63/u1.png 1200w,\n/static/a10eaa11ed554b28b204fd0840d62e00/fde66/u1.png 1574w\" sizes=\"(max-width: 800px) 100vw, 800px\"></picture>\n<p>The question arises of how best to handle the filter's state management. There are essentially two options: create a separate Zustand store for the filter, or add it to the existing store. Both solutions are justifiable. The <a href=\"https://tkdodo.eu/blog/working-with-zustand#keep-the-scope-of-your-store-small\">best practices</a> found online recommend keeping completely unrelated things in separate stores. However, the list of notes and filtering are closely enough related that we will place both in the same store:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> useNoteStore <span class=\"token operator\">=</span> <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token keyword\">set</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> initialNotes<span class=\"token punctuation\">,</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> <span class=\"token string\">'all'</span><span class=\"token punctuation\">,</span></span>  <span class=\"token literal-property property\">actions</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function-variable function\">add</span><span class=\"token operator\">:</span> <span class=\"token parameter\">note</span> <span class=\"token operator\">=></span> <span class=\"token function\">set</span><span class=\"token punctuation\">(</span>\n      <span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">.</span><span class=\"token function\">concat</span><span class=\"token punctuation\">(</span>note<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token function-variable function\">toggleImportance</span><span class=\"token operator\">:</span> <span class=\"token parameter\">id</span> <span class=\"token operator\">=></span> <span class=\"token function\">set</span><span class=\"token punctuation\">(</span>\n      <span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n        <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">note</span> <span class=\"token operator\">=></span>\n          note<span class=\"token punctuation\">.</span>id <span class=\"token operator\">===</span> id <span class=\"token operator\">?</span> <span class=\"token punctuation\">{</span> <span class=\"token operator\">...</span>note<span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token operator\">!</span>note<span class=\"token punctuation\">.</span>important <span class=\"token punctuation\">}</span> <span class=\"token operator\">:</span> note\n        <span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token function-variable function\">setFilter</span><span class=\"token operator\">:</span> <span class=\"token parameter\">value</span> <span class=\"token operator\">=></span> <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> value <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></span>  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">useNotes</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNoteStore</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> state<span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">)</span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">useFilter</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNoteStore</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> state<span class=\"token punctuation\">.</span>filter<span class=\"token punctuation\">)</span></span><span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">useNoteActions</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNoteStore</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> state<span class=\"token punctuation\">.</span>actions<span class=\"token punctuation\">)</span></code></pre></div>\n<p>The component that sets the filter value:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useNoteActions <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./store'</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">VisibilityFilter</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> setFilter <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">useNoteActions</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&lt;</span>div<span class=\"token operator\">></span>\n      <span class=\"token operator\">&lt;</span>input\n        type<span class=\"token operator\">=</span><span class=\"token string\">\"radio\"</span>\n        name<span class=\"token operator\">=</span><span class=\"token string\">\"filter\"</span>\n        onChange<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">setFilter</span><span class=\"token punctuation\">(</span><span class=\"token string\">'all'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span>\n        defaultChecked\n      <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n      all\n      <span class=\"token operator\">&lt;</span>input\n        type<span class=\"token operator\">=</span><span class=\"token string\">\"radio\"</span>\n        name<span class=\"token operator\">=</span><span class=\"token string\">\"filter\"</span>\n        onChange<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">setFilter</span><span class=\"token punctuation\">(</span><span class=\"token string\">'important'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span>\n      <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n      important\n      <span class=\"token operator\">&lt;</span>input\n        type<span class=\"token operator\">=</span><span class=\"token string\">\"radio\"</span>\n        name<span class=\"token operator\">=</span><span class=\"token string\">\"filter\"</span>\n        onChange<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">setFilter</span><span class=\"token punctuation\">(</span><span class=\"token string\">'nonimportant'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span>\n      <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n      not important\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> VisibilityFilter</code></pre></div>\n<p>The <i>App</i> component renders the filter:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">App</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>\n  <span class=\"token operator\">&lt;</span>div<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span>NoteForm <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token operator\">&lt;</span>VisibilityFilter <span class=\"token operator\">/</span><span class=\"token operator\">></span></span>    <span class=\"token operator\">&lt;</span>NoteList <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n  <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n<span class=\"token punctuation\">)</span></code></pre></div>\n<p>The filtering of the displayed notes could be handled in the <i>NoteList</i> component, for example as follows:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useNotes<span class=\"token punctuation\">,</span> useFilter <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./store'</span>\n<span class=\"token keyword\">import</span> Note <span class=\"token keyword\">from</span> <span class=\"token string\">'./Note'</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">NoteList</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> notes <span class=\"token operator\">=</span> <span class=\"token function\">useNotes</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> filter <span class=\"token operator\">=</span> <span class=\"token function\">useFilter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> notesToShow <span class=\"token operator\">=</span> notes<span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">note</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>filter <span class=\"token operator\">===</span> <span class=\"token string\">'important'</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> note<span class=\"token punctuation\">.</span>important</span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>filter <span class=\"token operator\">===</span> <span class=\"token string\">'nonimportant'</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token operator\">!</span>note<span class=\"token punctuation\">.</span>important</span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&lt;</span>ul<span class=\"token operator\">></span>\n<span class=\"gatsby-highlight-code-line\">      <span class=\"token punctuation\">{</span>notesToShow<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">note</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span></span>        <span class=\"token operator\">&lt;</span>Note key<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>note<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">}</span> note<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>note<span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n      <span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>ul<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>A better solution is reached by including the filtering logic directly in the store's <i>useNotes</i> function:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> create <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'zustand'</span>\n\n<span class=\"token keyword\">const</span> useNoteStore <span class=\"token operator\">=</span> <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token keyword\">set</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">useNotes</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> notes <span class=\"token operator\">=</span> <span class=\"token function\">useNoteStore</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> state<span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> filter <span class=\"token operator\">=</span> <span class=\"token function\">useNoteStore</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> state<span class=\"token punctuation\">.</span>filter<span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\"></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>filter <span class=\"token operator\">===</span> <span class=\"token string\">'important'</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> notes<span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> n<span class=\"token punctuation\">.</span>important<span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>filter <span class=\"token operator\">===</span> <span class=\"token string\">'nonimportant'</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> notes<span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> <span class=\"token operator\">!</span>n<span class=\"token punctuation\">.</span>important<span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\"></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">return</span> notes</span><span class=\"gatsby-highlight-code-line\"><span class=\"token punctuation\">}</span></span></code></pre></div>\n<p>The function <i>useNotes</i> thus always returns a list of notes filtered in the desired way. The consumer of the function, the <i>NoteList</i> component, doesn't even need to be aware of the filter's existence:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useNotes <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./store'</span>\n<span class=\"token keyword\">import</span> Note <span class=\"token keyword\">from</span> <span class=\"token string\">'./Note'</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">NoteList</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// component gets always the properly filtered set of notes</span>\n  <span class=\"token keyword\">const</span> notes <span class=\"token operator\">=</span> <span class=\"token function\">useNotes</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&lt;</span>ul<span class=\"token operator\">></span>\n      <span class=\"token punctuation\">{</span>notes<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">note</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>\n        <span class=\"token operator\">&lt;</span>Note key<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>note<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">}</span> note<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>note<span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n      <span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>ul<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The solution is elegant!</p>\n<blockquote>\n<h4>A possible alternative solution</h4>\n<p>An alternative would be to implement filtering directly inside a selector function, so that both the notes and the filter are read in a single <i>useNoteStore</i> call:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">useNotes</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNoteStore</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> notes<span class=\"token punctuation\">,</span> filter <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>filter <span class=\"token operator\">===</span> <span class=\"token string\">'important'</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> notes<span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> n<span class=\"token punctuation\">.</span>important<span class=\"token punctuation\">)</span>\n <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>filter <span class=\"token operator\">===</span> <span class=\"token string\">'nonimportant'</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> notes<span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> <span class=\"token operator\">!</span>n<span class=\"token punctuation\">.</span>important<span class=\"token punctuation\">)</span>\n <span class=\"token keyword\">return</span> notes\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>This approach does not work, however, as it leads to an infinite re-rendering loop when the filter is changed.</p>\n<p>The reason is as follows: Zustand compares the selector's return value using the <i>===</i> operator. Since <i>notes.filter(...)</i> creates a new array on every render, React always interprets it as a new state and triggers another render, which again creates a new array, and so on.</p>\n<p>The fix is to add <a href=\"https://zustand.docs.pmnd.rs/reference/hooks/use-shallow\">useShallow</a>, which replaces the <i>===</i> comparison with a shallow comparison: it compares the array elements one by one. If the content has not changed, it returns the old array reference instead of a new one, so React sees the state as stable and does not re-render.</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useShallow <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'zustand/react/shallow'</span>\n\n<span class=\"token comment\">//...</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">useNotes</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNoteStore</span><span class=\"token punctuation\">(</span><span class=\"token function\">useShallow</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> notes<span class=\"token punctuation\">,</span> filter <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>filter <span class=\"token operator\">===</span> <span class=\"token string\">'important'</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> notes<span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> n<span class=\"token punctuation\">.</span>important<span class=\"token punctuation\">)</span>\n <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>filter <span class=\"token operator\">===</span> <span class=\"token string\">'nonimportant'</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> notes<span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> <span class=\"token operator\">!</span>n<span class=\"token punctuation\">.</span>important<span class=\"token punctuation\">)</span>\n <span class=\"token keyword\">return</span> notes\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>The solution works, but it is slightly harder to understand. In the course material we use the earlier-presented version with two separate <i>useNoteStore</i> calls.</p>\n</blockquote>\n<p>The current code of the application is available in its entirety on <a href=\"https://github.com/fullstack-hy2020/zustand-notes/tree/part6-3\">GitHub</a>, in the branch <i>part6-3</i>.</p>\n</div>\n<div class=\"tasks\">\n<h3>Exercise 6.6</h3>\n<p>Let's continue with the anecdote application.</p>\n<h4>6.6 anecdotes, step5</h4>\n<p>Implement filtering of the anecdotes displayed in the application:</p>\n<picture><img src=\"/static/1665ded20b15958ef98ad6e92a140fd9/5a190/u3.png\" alt=\"A text field is added at the top; by typing in it the displayed anecdotes can be limited to those containing the string typed into the filter field\" srcset=\"/static/1665ded20b15958ef98ad6e92a140fd9/772e8/u3.png 200w,\n/static/1665ded20b15958ef98ad6e92a140fd9/e17e5/u3.png 400w,\n/static/1665ded20b15958ef98ad6e92a140fd9/5a190/u3.png 800w,\n/static/1665ded20b15958ef98ad6e92a140fd9/c1b63/u3.png 1200w,\n/static/1665ded20b15958ef98ad6e92a140fd9/07d7d/u3.png 1478w\" sizes=\"(max-width: 800px) 100vw, 800px\"></picture>\n<p>Create a <i>Filter</i> component for displaying the filter on screen. You can use the following as its starting point:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">Filter</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">handleChange</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">event</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// the value of the input field is in event.target.value</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">const</span> style <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token literal-property property\">marginBottom</span><span class=\"token operator\">:</span> <span class=\"token number\">10</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&lt;</span>div style<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>style<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n      filter <span class=\"token operator\">&lt;</span>input onChange<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>handleChange<span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> Filter</code></pre></div>\n</div>\n<div class=\"content\">\n<h3>Data to the server</h3>\n<p>Let's extend the application so that notes are stored in a backend. We'll use the <a href=\"/en/part2/getting_data_from_server\">JSON Server</a> familiar from Part 2.</p>\n<p>Save the initial state of the database to the file <i>db.json</i> at the root of the project:</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n  <span class=\"token property\">\"notes\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token punctuation\">{</span>\n      <span class=\"token property\">\"id\"</span><span class=\"token operator\">:</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span>\n      <span class=\"token property\">\"content\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Zustand is less complex than Redux\"</span><span class=\"token punctuation\">,</span>\n      <span class=\"token property\">\"important\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span>\n      <span class=\"token property\">\"id\"</span><span class=\"token operator\">:</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span>\n      <span class=\"token property\">\"content\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"React app benefits from custom hooks\"</span><span class=\"token punctuation\">,</span>\n      <span class=\"token property\">\"important\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span>\n      <span class=\"token property\">\"id\"</span><span class=\"token operator\">:</span> <span class=\"token number\">3</span><span class=\"token punctuation\">,</span>\n      <span class=\"token property\">\"content\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Remember to sleep well\"</span><span class=\"token punctuation\">,</span>\n      <span class=\"token property\">\"important\"</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">]</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Install JSON Server:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> <span class=\"token function\">install</span> json-server --save-dev</code></pre></div>\n<p>and add the following line to the <i>scripts</i> section of <i>package.json</i>:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token string-property property\">\"scripts\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token string-property property\">\"server\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"json-server -p 3001 db.json\"</span><span class=\"token punctuation\">,</span>\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Start JSON Server with the command <em>npm run server</em>.</p>\n<h3>Fetch API</h3>\n<p>In software development, one often has to consider whether to implement a certain feature using an external library or to take advantage of the native solutions provided by the environment. Both approaches have their own advantages and challenges.</p>\n<p>In earlier parts of this course we have used the <a href=\"https://axios-http.com/docs/intro\">Axios</a> library for making HTTP requests. Let's now get familiar with an alternative way to make HTTP requests using the native <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API\">Fetch API</a>.</p>\n<p>It is typical that an external library like <i>Axios</i> is implemented using other external libraries. For example, if you install Axios in a project with the command <i>npm install axios</i>, the console output is:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">npm</span> <span class=\"token function\">install</span> axios\n\nadded <span class=\"token number\">23</span> packages, and audited <span class=\"token number\">302</span> packages <span class=\"token keyword\">in</span> 1s\n\n<span class=\"token number\">71</span> packages are looking <span class=\"token keyword\">for</span> funding\n  run <span class=\"token variable\"><span class=\"token variable\">`</span><span class=\"token function\">npm</span> fund<span class=\"token variable\">`</span></span> <span class=\"token keyword\">for</span> details\n\nfound <span class=\"token number\">0</span> vulnerabilities</code></pre></div>\n<p>So the command would install not only the Axios library but over 20 other npm packages that Axios requires to work.</p>\n<p>The <i>Fetch API</i> offers a similar way to make HTTP requests as Axios, but using the Fetch API does not require installing external libraries. Application maintenance becomes easier when there are fewer libraries to update, and security also improves since the potential attack surface of the application is reduced. Application security and maintenance are touched upon in <a href=\"https://fullstackopen.com/en/part7/class_components_miscellaneous#security-in-react-and-node-applications\">Part 7</a> of the course.</p>\n<p>Making requests is done in practice by using the <i>fetch()</i> function. The syntax used has some differences compared to Axios. We'll also soon notice that Axios took care of some things for us and made our lives easier. We'll use the Fetch API now, however, because it is a widely-used native solution that every Full Stack developer should be familiar with.</p>\n<h3>Fetching data from the server</h3>\n<p>Let's create a function that fetches data from the backend in the file <i>src/services/notes.js</i>:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> baseUrl <span class=\"token operator\">=</span> <span class=\"token string\">'http://localhost:3001/notes'</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">getAll</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> response <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span>baseUrl<span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>response<span class=\"token punctuation\">.</span>ok<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Failed to fetch notes'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">const</span> data <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">return</span> data\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token punctuation\">{</span> getAll <span class=\"token punctuation\">}</span></code></pre></div>\n<p>Let's look more closely at the implementation of the <i>getAll</i> function. The notes are now fetched from the backend by calling the <i>fetch()</i> function, which has been given the backend URL as an argument. The request type is not separately specified, so <i>fetch</i> performs the default action, which is a GET request.</p>\n<p>When the response has arrived, we check whether the request succeeded by looking at the <i>response.ok</i> field and throw an error if necessary:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>response<span class=\"token punctuation\">.</span>ok<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Failed to fetch notes'</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The attribute <i>response.ok</i> gets the value <i>true</i> if the request succeeded, i.e., if the response status code is in the range 200-299. For all other status codes, such as 404 or 500, it gets the value <i>false</i>.</p>\n<p>Note that <i>fetch</i> does not automatically throw an error even if the response status code is, for example, 404. Error handling must be implemented manually, as we have done now.</p>\n<p>If the request succeeded, the data contained in the response is converted to JSON format:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> data <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p><i>fetch</i> does not automatically convert the data that may accompany the response to JSON format; the conversion must be done manually. It is also worth noting that <i>response.json()</i> is an asynchronous function, so the <i>await</i> keyword must be used with it.</p>\n<p>Let's simplify the code a bit by returning the data returned by the <i>response.json()</i> function directly:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">getAll</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> response <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span>baseUrl<span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>response<span class=\"token punctuation\">.</span>ok<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Failed to fetch notes'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">return</span> <span class=\"token keyword\">await</span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></span><span class=\"token punctuation\">}</span></code></pre></div>\n<p>Let's add a function to the store that can be used to initialize the state with notes fetched from the server:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> useNoteStore <span class=\"token operator\">=</span> <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token keyword\">set</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span></span>  <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">actions</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// ...</span>\n    <span class=\"token function-variable function\">setFilter</span><span class=\"token operator\">:</span> <span class=\"token parameter\">value</span> <span class=\"token operator\">=></span> <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> value <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token function-variable function\">initialize</span><span class=\"token operator\">:</span> <span class=\"token parameter\">notes</span> <span class=\"token operator\">=></span> <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> notes <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></span>  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>Let's implement the initialization of notes in the <i>App</i> component — as usual when fetching data from a server, we use the <i>useEffect</i> hook:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">App</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> initialize <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">useNoteActions</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    noteService<span class=\"token punctuation\">.</span><span class=\"token function\">getAll</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">notes</span> <span class=\"token operator\">=></span> <span class=\"token function\">initialize</span><span class=\"token punctuation\">(</span>notes<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>initialize<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&lt;</span>div<span class=\"token operator\">></span>\n      <span class=\"token operator\">&lt;</span>NoteForm <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&lt;</span>VisibilityFilter <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&lt;</span>NoteList <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The notes are thus fetched from the server using the  <i>getAll()</i> function we defined and then stored using the store's <i>initialize</i> function. These actions are done in the <i>useEffect</i> hook, meaning they are executed during the first render of the App component.</p>\n<p>Let's look more closely at one small detail. We have added the <i>initialize</i> function to the dependency array of the <i>useEffect</i> hook. If we try to use an empty dependency array, ESLint gives the following warning: <i>React Hook useEffect has a missing dependency: 'initialize'</i>. What is going on?</p>\n<p>The code would work logically exactly the same even if we used an empty dependency array, because <i>initialize</i> refers to the same function throughout the program's execution. However, it is good programming practice to add all variables and functions used by the <em>useEffect</em> hook that are defined inside the component to the dependencies. This helps avoid unexpected bugs.</p>\n<h3>Sending data to the server</h3>\n<p>Let's next implement the functionality for sending a new note to the server. At the same time we can practice how to make a POST request using the <i>fetch()</i> function.</p>\n<p>Let's extend the server communication code in <i>src/services/notes.js</i> as follows:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> baseUrl <span class=\"token operator\">=</span> <span class=\"token string\">'http://localhost:3001/notes'</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">getAll</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> response <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span>baseUrl<span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>response<span class=\"token punctuation\">.</span>ok<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Failed to fetch notes'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token keyword\">await</span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">createNew</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">content</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> response <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span>baseUrl<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token literal-property property\">method</span><span class=\"token operator\">:</span> <span class=\"token string\">'POST'</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token literal-property property\">headers</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span> <span class=\"token string-property property\">'Content-Type'</span><span class=\"token operator\">:</span> <span class=\"token string\">'application/json'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token literal-property property\">body</span><span class=\"token operator\">:</span> <span class=\"token constant\">JSON</span><span class=\"token punctuation\">.</span><span class=\"token function\">stringify</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> content<span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">  </span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>response<span class=\"token punctuation\">.</span>ok<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Failed to create note'</span><span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\">  </span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">return</span> <span class=\"token keyword\">await</span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token punctuation\">}</span></span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token punctuation\">{</span> getAll<span class=\"token punctuation\">,</span> createNew <span class=\"token punctuation\">}</span></span></code></pre></div>\n<p>Let's look more closely at the implementation of the <i>createNew</i> function. The first parameter of the <i>fetch()</i> function specifies the URL to which the request is made. The second parameter is an object that defines the other details of the request, such as the request type, headers and the data sent with the request. We can further clarify the code by storing the object defining the request details in a separate <i>options</i> helper variable:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">createNew</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">content</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> options <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token literal-property property\">method</span><span class=\"token operator\">:</span> <span class=\"token string\">'POST'</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token literal-property property\">headers</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span> <span class=\"token string-property property\">'Content-Type'</span><span class=\"token operator\">:</span> <span class=\"token string\">'application/json'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token literal-property property\">body</span><span class=\"token operator\">:</span> <span class=\"token constant\">JSON</span><span class=\"token punctuation\">.</span><span class=\"token function\">stringify</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> content<span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\">  </span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> response <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span>baseUrl<span class=\"token punctuation\">,</span> options<span class=\"token punctuation\">)</span></span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>response<span class=\"token punctuation\">.</span>ok<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Failed to create note'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n  \n  <span class=\"token keyword\">return</span> <span class=\"token keyword\">await</span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Let's look more closely at the <i>options</i> object:</p>\n<ul>\n<li><i>method</i> defines the request type, which in this case is <i>POST</i></li>\n<li><i>headers</i> defines the request headers. We attach the header <i>'Content-Type': 'application/json'</i> to the request so that the server knows that the data included with the request is in JSON format, and can handle the request correctly</li>\n<li><i>body</i> contains the data to be sent with the request. The field cannot directly contain a JavaScript object, it must first be converted to a JSON string by calling <i>JSON.stringify()</i></li>\n</ul>\n<p>As with the GET request, we also check the response status code here for errors:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>response<span class=\"token punctuation\">.</span>ok<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Failed to create note'</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>If the request succeeds, <i>JSON Server</i> returns the just-created note, for which it has also generated a unique <i>id</i>. The data contained in the response must still be converted to JSON format using the <i>response.json()</i> function: </p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">return</span> <span class=\"token keyword\">await</span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>Let's then change our application's <i>NoteForm</i> component so that a new note is sent to the backend. The component's <i>addNote</i> function changes slightly:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useNoteActions <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./store'</span>\n<span class=\"token keyword\">import</span> noteService <span class=\"token keyword\">from</span> <span class=\"token string\">'./services/notes'</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">NoteForm</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> add <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">useNoteActions</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">addNote</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    e<span class=\"token punctuation\">.</span><span class=\"token function\">preventDefault</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">const</span> content <span class=\"token operator\">=</span> e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>note<span class=\"token punctuation\">.</span>value\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">const</span> newNote <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> noteService<span class=\"token punctuation\">.</span><span class=\"token function\">createNew</span><span class=\"token punctuation\">(</span>content<span class=\"token punctuation\">)</span></span>    <span class=\"token function\">add</span><span class=\"token punctuation\">(</span>newNote<span class=\"token punctuation\">)</span>\n    e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span><span class=\"token function\">reset</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&lt;</span>form onSubmit<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>addNote<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&lt;</span>input name<span class=\"token operator\">=</span><span class=\"token string\">\"note\"</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&lt;</span>button type<span class=\"token operator\">=</span><span class=\"token string\">\"submit\"</span><span class=\"token operator\">></span>add<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>form<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> NoteForm</code></pre></div>\n<p>When a new note is created in the backend by calling the function <i>createNew()</i>, we get back an object describing the note, for which the backend has generated an <i>id</i>.</p>\n<p>The current code of the application is available in its entirety on <a href=\"https://github.com/fullstack-hy2020/zustand-notes/tree/part6-4\">GitHub</a>, in the branch <i>part6-4</i>.</p>\n<h3>Async actions</h3>\n<p>Our approach is fairly good, but in one sense unfortunate, in that the communication with the server happens inside the code of the functions that define the components. It would be better if the communication could be abstracted away from the components, so that they only need to call an appropriate function that the store provides.</p>\n<p>We want <i>App</i> to initialize the application state as follows:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">App</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> initialize <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">useNoteActions</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token function\">initialize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></span>  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>initialize<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&lt;</span>div<span class=\"token operator\">></span>\n      <span class=\"token operator\">&lt;</span>NoteForm <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&lt;</span>VisibilityFilter <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&lt;</span>NoteList <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><i>NoteForm</i> in turn creates a new note like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">NoteForm</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> add <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">useNoteActions</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></span>\n  <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">addNote</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    e<span class=\"token punctuation\">.</span><span class=\"token function\">preventDefault</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">const</span> content <span class=\"token operator\">=</span> e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>note<span class=\"token punctuation\">.</span>value\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">await</span> <span class=\"token function\">add</span><span class=\"token punctuation\">(</span>content<span class=\"token punctuation\">)</span></span>    e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span><span class=\"token function\">reset</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&lt;</span>form onSubmit<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>addNote<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&lt;</span>input name<span class=\"token operator\">=</span><span class=\"token string\">\"note\"</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&lt;</span>button type<span class=\"token operator\">=</span><span class=\"token string\">\"submit\"</span><span class=\"token operator\">></span>add<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>form<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The change to <i>store.js</i> is as follows:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> create <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'zustand'</span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">import</span> noteService <span class=\"token keyword\">from</span> <span class=\"token string\">'./services/notes'</span></span>\n<span class=\"token keyword\">const</span> useNoteStore <span class=\"token operator\">=</span> <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token keyword\">set</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">actions</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token function-variable function\">add</span><span class=\"token operator\">:</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">content</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">const</span> newNote <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> noteService<span class=\"token punctuation\">.</span><span class=\"token function\">createNew</span><span class=\"token punctuation\">(</span>content<span class=\"token punctuation\">)</span></span>      <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">.</span><span class=\"token function\">concat</span><span class=\"token punctuation\">(</span>newNote<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> \n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token function-variable function\">initialize</span><span class=\"token operator\">:</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">const</span> notes <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> noteService<span class=\"token punctuation\">.</span><span class=\"token function\">getAll</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></span>      <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> notes <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token comment\">// ...</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>The functions <i>add</i> and <i>initialize</i> have thus been changed into asynchronous functions, which first call the appropriate noteService function, and then update the state.</p>\n<p>The solution is elegant; state management and communication with the server are entirely separated outside of React components.</p>\n<p>Let's finalize the application by synchronizing the importance toggle change to the server.</p>\n<p><i>noteService.js</i> is extended as follows:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">update</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">id<span class=\"token punctuation\">,</span> note</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> response <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>baseUrl<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">/</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>id<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token literal-property property\">method</span><span class=\"token operator\">:</span> <span class=\"token string\">'PUT'</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">headers</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span> <span class=\"token string-property property\">'Content-Type'</span><span class=\"token operator\">:</span> <span class=\"token string\">'application/json'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">body</span><span class=\"token operator\">:</span> <span class=\"token constant\">JSON</span><span class=\"token punctuation\">.</span><span class=\"token function\">stringify</span><span class=\"token punctuation\">(</span>note<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>response<span class=\"token punctuation\">.</span>ok<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Failed to update note'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token keyword\">await</span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token punctuation\">{</span> getAll<span class=\"token punctuation\">,</span> createNew<span class=\"token punctuation\">,</span> update <span class=\"token punctuation\">}</span> </code></pre></div>\n<p>The change to the store's <i>toggleImportance</i> function is as follows:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> useNoteStore <span class=\"token operator\">=</span> <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token keyword\">set</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">actions</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function-variable function\">add</span><span class=\"token operator\">:</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">content</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">const</span> newNote <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> noteService<span class=\"token punctuation\">.</span><span class=\"token function\">createNew</span><span class=\"token punctuation\">(</span>content<span class=\"token punctuation\">)</span>\n      <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">.</span><span class=\"token function\">concat</span><span class=\"token punctuation\">(</span>newNote<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token function-variable function\">toggleImportance</span><span class=\"token operator\">:</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">id</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">const</span> note <span class=\"token operator\">=</span> useNoteStore<span class=\"token punctuation\">.</span><span class=\"token function\">getState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">.</span><span class=\"token function\">find</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> n<span class=\"token punctuation\">.</span>id <span class=\"token operator\">===</span> id<span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">const</span> updated <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> noteService<span class=\"token punctuation\">.</span><span class=\"token function\">update</span><span class=\"token punctuation\">(</span></span><span class=\"gatsby-highlight-code-line\">        id<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> <span class=\"token operator\">...</span>note<span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token operator\">!</span>note<span class=\"token punctuation\">.</span>important <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">        <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> n<span class=\"token punctuation\">.</span>id <span class=\"token operator\">===</span> id <span class=\"token operator\">?</span> updated <span class=\"token operator\">:</span> n<span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span></span>    <span class=\"token function-variable function\">setFilter</span><span class=\"token operator\">:</span> <span class=\"token parameter\">value</span> <span class=\"token operator\">=></span> <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> value <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token function-variable function\">initialize</span><span class=\"token operator\">:</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">const</span> notes <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> noteService<span class=\"token punctuation\">.</span><span class=\"token function\">getAll</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n      <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> notes <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>There is one noteworthy detail in the new function. The function receives the note's id as a parameter. However, the modified note must be sent to the backend. It can be found by calling the store's <i>getState</i> function:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> note <span class=\"token operator\">=</span> useNoteStore<span class=\"token punctuation\">.</span><span class=\"token function\">getState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">.</span><span class=\"token function\">find</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> n<span class=\"token punctuation\">.</span>id <span class=\"token operator\">===</span> id<span class=\"token punctuation\">)</span></code></pre></div>\n<p>Zustand stores also have a number of other <a href=\"https://zustand.docs.pmnd.rs/reference/apis/create#returns\">helper functions</a>, which may be useful in some situations.</p>\n<p>Let's however also change the store definition so that we also pass the parameter <i>get</i> to the function given to <i>create</i>, through which we can then access the state values when needed:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">const</span> useNoteStore <span class=\"token operator\">=</span> <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">set<span class=\"token punctuation\">,</span> <span class=\"token keyword\">get</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span></span>  <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">actions</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function-variable function\">toggleImportance</span><span class=\"token operator\">:</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">id</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">const</span> note <span class=\"token operator\">=</span> <span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">.</span><span class=\"token function\">find</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> n<span class=\"token punctuation\">.</span>id <span class=\"token operator\">===</span> id<span class=\"token punctuation\">)</span></span>      <span class=\"token keyword\">const</span> updated <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> noteService<span class=\"token punctuation\">.</span><span class=\"token function\">update</span><span class=\"token punctuation\">(</span>\n        id<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> <span class=\"token operator\">...</span>note<span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token operator\">!</span>note<span class=\"token punctuation\">.</span>important <span class=\"token punctuation\">}</span>\n      <span class=\"token punctuation\">)</span>\n      <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n        <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> n<span class=\"token punctuation\">.</span>id <span class=\"token operator\">===</span> id <span class=\"token operator\">?</span> updated <span class=\"token operator\">:</span> n<span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token comment\">// ...</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>The function <i>get</i> returns the current state of the store. For example, the call <i>get().notes</i> gives the store's current notes. The function <i>get</i> is functionally equivalent to calling <i>useNoteStore.getState()</i>, but is the most idiomatic way to refer to the store's state from within the store's own functions.</p>\n<p>The code of the application is on <a href=\"https://github.com/fullstack-hy2020/zustand-notes/tree/part6-5\">GitHub</a> in the branch <i>part6-5</i>.</p>\n</div>\n<div class=\"tasks\">\n<h3>Exercises 6.7.-6.11.</h3>\n<h4>6.7 anecdotes, step6</h4>\n<p>Fetch the anecdotes from the JSON Server backend when the application starts. Use the Fetch API to make the HTTP request.</p>\n<p>You can find the initial content for the backend e.g. <a href=\"https://github.com/fullstack-hy2020/misc/blob/master/anecdotes.json\">here</a>.</p>\n<h4>6.8 anecdotes, step7</h4>\n<p>Change the creation of new anecdotes so that anecdotes are stored in the backend. Use the Fetch API in your implementation.</p>\n<h4>6.9 anecdotes, step8</h4>\n<p>Voting does not yet save changes to the backend. Fix the situation.</p>\n<h4>6.10 anecdotes, step9</h4>\n<p>The application has a ready-made skeleton for the <i>Notification</i> component:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">Notification</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> style <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token literal-property property\">border</span><span class=\"token operator\">:</span> <span class=\"token string\">'solid'</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">padding</span><span class=\"token operator\">:</span> <span class=\"token number\">10</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">borderWidth</span><span class=\"token operator\">:</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">marginBottom</span><span class=\"token operator\">:</span> <span class=\"token number\">10</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&lt;</span>div style<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>style<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n      render here notification<span class=\"token operator\">...</span>\n    <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> Notification</code></pre></div>\n<p>Extend the application so that it shows a notification using the <i>Notification</i> component for five seconds when anecdotes are voted on or new anecdotes are created:</p>\n<picture><img src=\"/static/c4f460152b68a605ba70ae47ef09301e/5a190/8eb.png\" alt=\"A notification is shown when voting: you voted &#x27;if it hurts, do it more often&#x27;\" srcset=\"/static/c4f460152b68a605ba70ae47ef09301e/772e8/8eb.png 200w,\n/static/c4f460152b68a605ba70ae47ef09301e/e17e5/8eb.png 400w,\n/static/c4f460152b68a605ba70ae47ef09301e/5a190/8eb.png 800w,\n/static/c4f460152b68a605ba70ae47ef09301e/35a31/8eb.png 1028w\" sizes=\"(max-width: 800px) 100vw, 800px\"></picture>\n<p>Use Zustand for notification state management. It may be a good idea to create a separate Zustand store for notifications, since notification usage may expand to other areas of the application as it grows, such as user login.</p>\n<h4>6.11 anecdotes, step10</h4>\n<p>We notice that some of the anecdotes added by users are not very good. Implement a feature that allows deleting anecdotes that have zero votes.</p>\n</div>\n<div class=\"content\">\n<h3>Middlewares</h3>\n<p>When developing an application, one often encounters situations where it is hard to understand why the application behaves unexpectedly. The state changes as a result of some action function call, but it is unclear which call changed what and in which order. Traditional console logging of individual functions only helps to a limited extent.</p>\n<p>Zustand supports so-called middlewares, which can be used to add functionality to stores transparently, without touching the store's own logic. The idea of middleware is simple: it \"wraps\" around the store and can, for example, automatically log every state change.</p>\n<p>The form of middleware functions is somewhat cryptic. Below is a <i>logger</i> that always prints the store's old and new state whenever the state changes:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">logger</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">config</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">set<span class=\"token punctuation\">,</span> <span class=\"token keyword\">get</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">config</span><span class=\"token punctuation\">(</span>\n  <span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token operator\">...</span>args</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'prev state'</span><span class=\"token punctuation\">,</span> <span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token operator\">...</span>args<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'next state'</span><span class=\"token punctuation\">,</span> <span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  get\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The middleware is activated by \"wrapping\" the function given to Zustand's <i>create</i> as its parameter:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">const</span> useNoteStore <span class=\"token operator\">=</span> <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token function\">logger</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">set<span class=\"token punctuation\">,</span> <span class=\"token keyword\">get</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span></span>  <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">actions</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// ...</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></span></code></pre></div>\n<p>Now whenever the store's state changes, we can always see in the console how the state changes:</p>\n<picture><img src=\"/static/b789265b6af129ff09dd51d1fe46259b/5a190/u4.png\" srcset=\"/static/b789265b6af129ff09dd51d1fe46259b/772e8/u4.png 200w,\n/static/b789265b6af129ff09dd51d1fe46259b/e17e5/u4.png 400w,\n/static/b789265b6af129ff09dd51d1fe46259b/5a190/u4.png 800w,\n/static/b789265b6af129ff09dd51d1fe46259b/c1b63/u4.png 1200w,\n/static/b789265b6af129ff09dd51d1fe46259b/29007/u4.png 1600w,\n/static/b789265b6af129ff09dd51d1fe46259b/8d9a9/u4.png 2244w\" sizes=\"(max-width: 800px) 100vw, 800px\"></picture>\n<p>In practice our defined middleware works by replacing the original function <i>set</i> with the function</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\">  <span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token operator\">...</span>args</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'prev state'</span><span class=\"token punctuation\">,</span> <span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token operator\">...</span>args<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'next state'</span><span class=\"token punctuation\">,</span> <span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span></code></pre></div>\n<p>which in addition to calling <i>set</i>, also prints the old and new state (accessible via the <i>get</i> function) to the console. The second parameter is the old <i>get</i> unchanged.</p>\n<p>Zustand also has a ready-made <i>devtools</i> middleware that integrates the store with the browser's <a href=\"https://chromewebstore.google.com/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd\">Redux DevTools</a> extension. Devtools is an extremely useful development tool, as it allows you to visually track state changes.</p>\n<p>The setup is straightforward:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> create <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'zustand'</span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> devtools <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'zustand/middleware'</span></span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">const</span> useNoteStore <span class=\"token operator\">=</span> <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token function\">devtools</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">set<span class=\"token punctuation\">,</span> <span class=\"token keyword\">get</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span></span>  <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">actions</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// ...</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></span></code></pre></div>\n<p>When the Redux DevTools extension is installed in the browser, the state of the store and its changes can be inspected in the browser's developer tools:</p>\n<picture><img src=\"/static/9d3b0d250c37dab1dd5d32a163cd6035/5a190/u6.png\" alt=\"Redux DevTools view in browser: on the left a list of state changes, on the right the state contents in tree form\" srcset=\"/static/9d3b0d250c37dab1dd5d32a163cd6035/772e8/u6.png 200w,\n/static/9d3b0d250c37dab1dd5d32a163cd6035/e17e5/u6.png 400w,\n/static/9d3b0d250c37dab1dd5d32a163cd6035/5a190/u6.png 800w,\n/static/9d3b0d250c37dab1dd5d32a163cd6035/c1b63/u6.png 1200w,\n/static/9d3b0d250c37dab1dd5d32a163cd6035/29007/u6.png 1600w,\n/static/9d3b0d250c37dab1dd5d32a163cd6035/d544a/u6.png 1950w\" sizes=\"(max-width: 800px) 100vw, 800px\"></picture>\n<h3>Testing Zustand stores</h3>\n<p>Finally, let's look at testing Zustand stores with Vitest.</p>\n<p>For simplicity, let's start with the counter store:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> create <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'zustand'</span>\n\n<span class=\"token keyword\">const</span> useCounterStore <span class=\"token operator\">=</span> <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token keyword\">set</span></span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token literal-property property\">counter</span><span class=\"token operator\">:</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">actions</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function-variable function\">increment</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">counter</span><span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>counter <span class=\"token operator\">+</span> <span class=\"token number\">1</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token function-variable function\">decrement</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">counter</span><span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>counter <span class=\"token operator\">-</span> <span class=\"token number\">1</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token function-variable function\">zero</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">counter</span><span class=\"token operator\">:</span> <span class=\"token number\">0</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span>  \n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">useCounter</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useCounterStore</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> state<span class=\"token punctuation\">.</span>counter<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">useCounterControls</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useCounterStore</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> state<span class=\"token punctuation\">.</span>actions<span class=\"token punctuation\">)</span>\n\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> useCounterStore</span></code></pre></div>\n<p>We added an export to the definition for the tests, through which the test can access the store.</p>\n<p>Let's install Vitest:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm install --save-dev vitest</code></pre></div>\n<p>Let's implement the test in the file <i>store.test.js</i>:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> beforeEach<span class=\"token punctuation\">,</span> describe<span class=\"token punctuation\">,</span> expect<span class=\"token punctuation\">,</span> it <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'vitest'</span>\n<span class=\"token keyword\">import</span> useCounterStore <span class=\"token keyword\">from</span> <span class=\"token string\">'./store'</span>\n\n<span class=\"token function\">beforeEach</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  useCounterStore<span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">counter</span><span class=\"token operator\">:</span> <span class=\"token number\">0</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token function\">describe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'counter store'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'initial state is 0'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>useCounterStore<span class=\"token punctuation\">.</span><span class=\"token function\">getState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>counter<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'increment increases counter by 1'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    useCounterStore<span class=\"token punctuation\">.</span><span class=\"token function\">getState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>actions<span class=\"token punctuation\">.</span><span class=\"token function\">increment</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>useCounterStore<span class=\"token punctuation\">.</span><span class=\"token function\">getState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>counter<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'decrement decreases counter by 1'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    useCounterStore<span class=\"token punctuation\">.</span><span class=\"token function\">getState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>actions<span class=\"token punctuation\">.</span><span class=\"token function\">decrement</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>useCounterStore<span class=\"token punctuation\">.</span><span class=\"token function\">getState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>counter<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'zero resets counter to 0'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    useCounterStore<span class=\"token punctuation\">.</span><span class=\"token function\">getState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>actions<span class=\"token punctuation\">.</span><span class=\"token function\">increment</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    useCounterStore<span class=\"token punctuation\">.</span><span class=\"token function\">getState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>actions<span class=\"token punctuation\">.</span><span class=\"token function\">increment</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    useCounterStore<span class=\"token punctuation\">.</span><span class=\"token function\">getState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>actions<span class=\"token punctuation\">.</span><span class=\"token function\">zero</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>useCounterStore<span class=\"token punctuation\">.</span><span class=\"token function\">getState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>counter<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>The tests are quite straightforward, utilizing the store's <a href=\"https://zustand.docs.pmnd.rs/reference/apis/create#returns\">getState</a> function, which allows them to read the store's state and execute the store's functions.</p>\n<p>Before each test, the store is reset to its initial state in the <i>beforeEach</i> block using the store's <a href=\"https://zustand.docs.pmnd.rs/reference/apis/create#returns\">setState</a> function.</p>\n<p>Resetting the store to its initial state is simple in our case. This is not always necessarily so. Zustand's <a href=\"https://zustand.docs.pmnd.rs/learn/guides/testing#vitest\">documentation</a> describes a way to create a version of stores for testing that is automatically reset to its initial state before each test. The method is, however, complex enough and unnecessary for us that we will skip it for now.</p>\n<p>The tests thus use the store directly. If more complex logic has been implemented through custom hooks for using the store, it may be necessary to write tests that also utilize the hooks. In the counter, store usage happens through the hooks <i>useCounter</i> and <i>useCounterControls</i>:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> useCounterStore <span class=\"token operator\">=</span> <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token keyword\">set</span></span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\">// hightlight-start</span>\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">useCounter</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useCounterStore</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> state<span class=\"token punctuation\">.</span>counter<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">useCounterControls</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useCounterStore</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> state<span class=\"token punctuation\">.</span>actions<span class=\"token punctuation\">)</span>\n<span class=\"token comment\">// hightlight-end</span></code></pre></div>\n<p>In this case the hooks do not contain any logic, they just separately expose the value stored in the store and the store's functions. The testing approach we used above is therefore perfectly fine.</p>\n<p>Let's however make another version of the tests for example purposes, where the store is used in exactly the same way as the application uses it.</p>\n<p><i>useCounter</i> and <i>useCounterControls</i> are React hooks, so testing them requires <a href=\"https://github.com/testing-library/react-testing-library\">React Testing Library</a> and the <a href=\"https://github.com/jsdom/jsdom\">jsdom</a> library:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm install --save-dev @testing-library/react jsdom</code></pre></div>\n<p>Let's add the testing environment configuration to <i>vite.config.js</i>:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> defineConfig <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'vite'</span>\n<span class=\"token keyword\">import</span> react <span class=\"token keyword\">from</span> <span class=\"token string\">'@vitejs/plugin-react'</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token function\">defineConfig</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token literal-property property\">plugins</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token function\">react</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token literal-property property\">test</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token literal-property property\">environment</span><span class=\"token operator\">:</span> <span class=\"token string\">'jsdom'</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span></span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>The tests are as follows:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> beforeEach<span class=\"token punctuation\">,</span> describe<span class=\"token punctuation\">,</span> expect<span class=\"token punctuation\">,</span> it <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'vitest'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> renderHook<span class=\"token punctuation\">,</span> act <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@testing-library/react'</span>\n<span class=\"token keyword\">import</span> useCounterStore<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> useCounter<span class=\"token punctuation\">,</span> useCounterControls <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./store'</span>\n\n<span class=\"token function\">beforeEach</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  useCounterStore<span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">counter</span><span class=\"token operator\">:</span> <span class=\"token number\">0</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token function\">describe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'counter hooks'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'useCounter returns initial value of 0'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> result <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useCounter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'increment updates counter'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">result</span><span class=\"token operator\">:</span> counter <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useCounter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">result</span><span class=\"token operator\">:</span> controls <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useCounterControls</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token function\">act</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> controls<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">increment</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>counter<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'decrement updates counter'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">result</span><span class=\"token operator\">:</span> counter <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useCounter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">result</span><span class=\"token operator\">:</span> controls <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useCounterControls</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token function\">act</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> controls<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">decrement</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>counter<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'zero resets counter'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">result</span><span class=\"token operator\">:</span> counter <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useCounter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">result</span><span class=\"token operator\">:</span> controls <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useCounterControls</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token function\">act</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      controls<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">increment</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n      controls<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">increment</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n      controls<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">zero</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>counter<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>There are a few interesting things in the test. At the start of the tests, the hooks are rendered using the <a href=\"https://testing-library.com/docs/react-testing-library/api/#renderhook\">renderHook</a> function:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">result</span><span class=\"token operator\">:</span> counter <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useCounter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">result</span><span class=\"token operator\">:</span> controls <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useCounterControls</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>This way the test gets access to the values returned by the hooks, which are stored in the variables <i>counter</i> and <i>controls</i>.</p>\n<p>The hooks are called by wrapping the call inside the <a href=\"https://testing-library.com/docs/react-testing-library/api/#act\">act</a> function:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token function\">act</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  controls<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">increment</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  controls<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">increment</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  controls<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">zero</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>Lopuksi tapahtuu testin ekspektaatio:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>counter<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>As we can see, to access the hook itself we still need to take the <i>current</i> field from the object returned by <i>renderHook</i>, which corresponds to the hook's current value.</p>\n<blockquote>\n<h4>What is act?</h4>\n<p><i>act</i> is a helper function that ensures all state updates and their side effects have been processed before the test code continues.</p>\n<p>When a state change occurs in a React component or hook, React does not update the state immediately but queues the updates. act forces these queued updates to be executed.</p>\n<p>Without act, a test might check the state before React has had time to update it, causing the test to fail or give incorrect results.</p>\n<p>React Testing Library wraps many of its functions (such as fireEvent, userEvent) in act automatically, but when testing hooks directly it is usually needed.</p>\n</blockquote>\n<p>Testing via hooks uses React Testing Library and renders the hooks in a real React context using jsdom. This approach is considerably slower than tests that use the store directly, so if the hooks do not contain complex logic, it may be sufficient to run the tests using the store directly.</p>\n<p>The code containing the Zustand counter tests is available on <a href=\"https://github.com/fullstack-hy2020/zustand-counter\">GitHub</a>.</p>\n<h3>Testing the notes store</h3>\n<p>Testing the store of the note application is a somewhat more challenging case, since the store contains asynchronous functions that call the server:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> create <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'zustand'</span>\n<span class=\"token keyword\">import</span> noteService <span class=\"token keyword\">from</span> <span class=\"token string\">'./services/notes'</span>\n\n<span class=\"token keyword\">const</span> useNoteStore <span class=\"token operator\">=</span> <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token keyword\">set</span></span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">actions</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function-variable function\">add</span><span class=\"token operator\">:</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">content</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">const</span> newNote <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> noteService<span class=\"token punctuation\">.</span><span class=\"token function\">createNew</span><span class=\"token punctuation\">(</span>content<span class=\"token punctuation\">)</span></span>      <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">.</span><span class=\"token function\">concat</span><span class=\"token punctuation\">(</span>newNote<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token function-variable function\">toggleImportance</span><span class=\"token operator\">:</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">id</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">const</span> note <span class=\"token operator\">=</span> useNoteStore<span class=\"token punctuation\">.</span><span class=\"token function\">getState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">.</span><span class=\"token function\">find</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> n<span class=\"token punctuation\">.</span>id <span class=\"token operator\">===</span> id<span class=\"token punctuation\">)</span>\n<span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">const</span> updated <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> noteService<span class=\"token punctuation\">.</span><span class=\"token function\">update</span><span class=\"token punctuation\">(</span></span><span class=\"gatsby-highlight-code-line\">        id<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> <span class=\"token operator\">...</span>note<span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token operator\">!</span>note<span class=\"token punctuation\">.</span>important <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token punctuation\">)</span></span>      <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n        <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> n<span class=\"token punctuation\">.</span>id <span class=\"token operator\">===</span> id <span class=\"token operator\">?</span> updated <span class=\"token operator\">:</span> n<span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token function-variable function\">setFilter</span><span class=\"token operator\">:</span> <span class=\"token parameter\">value</span> <span class=\"token operator\">=></span> <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> value <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token function-variable function\">initialize</span><span class=\"token operator\">:</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">const</span> notes <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> noteService<span class=\"token punctuation\">.</span><span class=\"token function\">getAll</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></span>      <span class=\"token function\">set</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> notes <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">useNotes</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span> \n  <span class=\"token keyword\">const</span> notes <span class=\"token operator\">=</span> <span class=\"token function\">useNoteStore</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> state<span class=\"token punctuation\">.</span>notes<span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">const</span> filter <span class=\"token operator\">=</span> <span class=\"token function\">useNoteStore</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> state<span class=\"token punctuation\">.</span>filter<span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>filter <span class=\"token operator\">===</span> <span class=\"token string\">'important'</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> notes<span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> n<span class=\"token punctuation\">.</span>important<span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>filter <span class=\"token operator\">===</span> <span class=\"token string\">'nonimportant'</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> notes<span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span> <span class=\"token operator\">=></span> <span class=\"token operator\">!</span>n<span class=\"token punctuation\">.</span>important<span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">return</span> notes\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">useFilter</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNoteStore</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> state<span class=\"token punctuation\">.</span>filter<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">useNoteActions</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNoteStore</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> state<span class=\"token punctuation\">.</span>actions<span class=\"token punctuation\">)</span></code></pre></div>\n<p>This time <i>useNotes</i> also contains a significant amount of logic, so testing should probably be done via hooks with React Testing Library.</p>\n<p>Let's install the required libraries:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm install --save-dev vitest @testing-library/react jsdom</code></pre></div>\n<p>Let's add the testing environment configuration to <i>vite.config.js</i>:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> defineConfig <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'vite'</span>\n<span class=\"token keyword\">import</span> react <span class=\"token keyword\">from</span> <span class=\"token string\">'@vitejs/plugin-react'</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token function\">defineConfig</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token literal-property property\">plugins</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token function\">react</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token literal-property property\">test</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token literal-property property\">environment</span><span class=\"token operator\">:</span> <span class=\"token string\">'jsdom'</span><span class=\"token punctuation\">,</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span></span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>The first part of the tests is as follows:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> describe<span class=\"token punctuation\">,</span> it<span class=\"token punctuation\">,</span> expect<span class=\"token punctuation\">,</span> beforeEach<span class=\"token punctuation\">,</span> vi <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'vitest'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> renderHook<span class=\"token punctuation\">,</span> act <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@testing-library/react'</span>\n\nvi<span class=\"token punctuation\">.</span><span class=\"token function\">mock</span><span class=\"token punctuation\">(</span><span class=\"token string\">'./services/notes'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">default</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token literal-property property\">getAll</span><span class=\"token operator\">:</span> vi<span class=\"token punctuation\">.</span><span class=\"token function\">fn</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">createNew</span><span class=\"token operator\">:</span> vi<span class=\"token punctuation\">.</span><span class=\"token function\">fn</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">update</span><span class=\"token operator\">:</span> vi<span class=\"token punctuation\">.</span><span class=\"token function\">fn</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">import</span> noteService <span class=\"token keyword\">from</span> <span class=\"token string\">'./services/notes'</span>\n<span class=\"token keyword\">import</span> useNoteStore<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> useNotes<span class=\"token punctuation\">,</span> useFilter<span class=\"token punctuation\">,</span> useNoteActions <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./store'</span>\n\n<span class=\"token function\">beforeEach</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  useNoteStore<span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n  vi<span class=\"token punctuation\">.</span><span class=\"token function\">clearAllMocks</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token function\">describe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'useNoteActions'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'initialize loads notes from service'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> mockNotes <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">id</span><span class=\"token operator\">:</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">content</span><span class=\"token operator\">:</span> <span class=\"token string\">'Test'</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span>\n    noteService<span class=\"token punctuation\">.</span>getAll<span class=\"token punctuation\">.</span><span class=\"token function\">mockResolvedValue</span><span class=\"token punctuation\">(</span>mockNotes<span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> result <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNoteActions</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">await</span> <span class=\"token function\">act</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">await</span> result<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">initialize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">result</span><span class=\"token operator\">:</span> notesResult <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNotes</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>notesResult<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toEqual</span><span class=\"token punctuation\">(</span>mockNotes<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'add appends a new note'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> newNote <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">id</span><span class=\"token operator\">:</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">content</span><span class=\"token operator\">:</span> <span class=\"token string\">'New note'</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span> <span class=\"token punctuation\">}</span>\n    noteService<span class=\"token punctuation\">.</span>createNew<span class=\"token punctuation\">.</span><span class=\"token function\">mockResolvedValue</span><span class=\"token punctuation\">(</span>newNote<span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> result <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNoteActions</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">await</span> <span class=\"token function\">act</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">await</span> result<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span><span class=\"token string\">'New note'</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">result</span><span class=\"token operator\">:</span> notesResult <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNotes</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>notesResult<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toContainEqual</span><span class=\"token punctuation\">(</span>newNote<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'toggleImportance flips important flag'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> note <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">id</span><span class=\"token operator\">:</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">content</span><span class=\"token operator\">:</span> <span class=\"token string\">'Test'</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span> <span class=\"token punctuation\">}</span>\n    useNoteStore<span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>note<span class=\"token punctuation\">]</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    noteService<span class=\"token punctuation\">.</span>update<span class=\"token punctuation\">.</span><span class=\"token function\">mockResolvedValue</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token operator\">...</span>note<span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> result <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNoteActions</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">await</span> <span class=\"token function\">act</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">await</span> result<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">toggleImportance</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">result</span><span class=\"token operator\">:</span> notesResult <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNotes</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>notesResult<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>important<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>There is a lot to digest in the tests. The tests create, using Vitest, a <a href=\"https://vitest.dev/guide/mocking\">mock</a> version of the <i>noteService</i> responsible for communicating with the server:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> describe<span class=\"token punctuation\">,</span> it<span class=\"token punctuation\">,</span> expect<span class=\"token punctuation\">,</span> beforeEach<span class=\"token punctuation\">,</span> vi <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'vitest'</span>\n\nvi<span class=\"token punctuation\">.</span><span class=\"token function\">mock</span><span class=\"token punctuation\">(</span><span class=\"token string\">'./services/notes'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">default</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token literal-property property\">getAll</span><span class=\"token operator\">:</span> vi<span class=\"token punctuation\">.</span><span class=\"token function\">fn</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">createNew</span><span class=\"token operator\">:</span> vi<span class=\"token punctuation\">.</span><span class=\"token function\">fn</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">update</span><span class=\"token operator\">:</span> vi<span class=\"token punctuation\">.</span><span class=\"token function\">fn</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p><a href=\"https://vitest.dev/api/vi.html#vi-mock\">vi.mock</a> replaces the <i>noteService</i> in the <i>./services/notes</i> module with its own version, where all functions are replaced with mock functions returned by <a href=\"https://vitest.dev/api/vi.html#vi-fn\">vi.fn</a>.</p>\n<p>Before each test, the store is reset to its initial state and the mock functions are cleared:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token function\">beforeEach</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  useNoteStore<span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">notes</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n  vi<span class=\"token punctuation\">.</span><span class=\"token function\">clearAllMocks</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>At the start of each test, the mocked <i>noteService</i> is told via the <a href=\"https://vitest.dev/api/mock.html#mockresolvedvalue\">mockResolvedValue</a> function how it should behave in the context of the test:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'initialize loads notes from service'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> mockNotes <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">id</span><span class=\"token operator\">:</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">content</span><span class=\"token operator\">:</span> <span class=\"token string\">'Test'</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span></span><span class=\"gatsby-highlight-code-line\">  noteService<span class=\"token punctuation\">.</span>getAll<span class=\"token punctuation\">.</span><span class=\"token function\">mockResolvedValue</span><span class=\"token punctuation\">(</span>mockNotes<span class=\"token punctuation\">)</span></span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> result <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNoteActions</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">await</span> <span class=\"token function\">act</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">await</span> result<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">initialize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">result</span><span class=\"token operator\">:</span> notesResult <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNotes</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n  <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>notesResult<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toEqual</span><span class=\"token punctuation\">(</span>mockNotes<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>First, the test defines that when the <i>noteService.getAll</i> function is called, the notes in the <i>mockNotes</i> array are returned to the store.</p>\n<p>The thing being tested is the call to the <i>initialize</i> function:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">await</span> <span class=\"token function\">act</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">await</span> result<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">initialize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>Since this is an asynchronous function, the completion of the call must be awaited with the <i>await</i> keyword.</p>\n<p>Finally, the test verifies that the store's state contains the same list of notes that the mocked <i>noteService.getAll</i> returned:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">result</span><span class=\"token operator\">:</span> notesResult <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNotes</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n<span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>notesResult<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toEqual</span><span class=\"token punctuation\">(</span>mockNotes<span class=\"token punctuation\">)</span></code></pre></div>\n<p>The other tests follow the same pattern: first, what the store's called <i>noteService</i> function returns is defined, and then the actual test is run.</p>\n<p>The second part of the tests verifies that filtering works correctly:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token function\">describe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'useNotes filtering'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> notes <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">id</span><span class=\"token operator\">:</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">content</span><span class=\"token operator\">:</span> <span class=\"token string\">'A'</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">id</span><span class=\"token operator\">:</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">content</span><span class=\"token operator\">:</span> <span class=\"token string\">'B'</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">important</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">]</span>\n\n  <span class=\"token function\">beforeEach</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    useNoteStore<span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> notes <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'returns all notes with no filter'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> result <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNotes</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toHaveLength</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'filters important notes'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    useNoteStore<span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> notes<span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> <span class=\"token string\">'important'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> result <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNotes</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toEqual</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span>notes<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'filters nonimportant notes'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    useNoteStore<span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> notes<span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">filter</span><span class=\"token operator\">:</span> <span class=\"token string\">'nonimportant'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> result <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">renderHook</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">useNotes</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toEqual</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span>notes<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>The state is initialized with two notes, one of which is important and the other is not. The three test cases verify that <i>useNotes</i> returns the correct notes for all filter values.</p>\n<p>The application's final code is on <a href=\"https://github.com/fullstack-hy2020/zustand-notes/tree/part6-6\">GitHub</a> in the branch <i>part6-6</i>.</p>\n</div>\n<div class=\"tasks\">\n<h3>Exercises 6.12.-6.15.</h3>\n<h4>6.12 Anecdotes, step11</h4>\n<p>Write a test that verifies the state is initialized with the anecdotes returned by the backend.</p>\n<h4>6.13 Anecdotes, step12</h4>\n<p>Write a test that verifies the component displaying anecdotes receives the anecdotes from the store sorted by votes.</p>\n<h4>6.14 Anecdotes, step13</h4>\n<p>Write a test that verifies the correct React component receives a properly filtered list of anecdotes.</p>\n<h4>6.15 Anecdotes, step14</h4>\n<p>Write a test that verifies that voting increases the number of votes for an anecdote.</p>\n</div>","frontmatter":{"mainImage":{"publicURL":"/static/a3b7bc3fafcb5b47227616e1343970e5/part-6.svg"},"part":6,"letter":"b","lang":"en"}}},"pageContext":{"part":6,"letter":"b","lang":"en"}},"staticQueryHashes":["3128451518"]}