{"componentChunkName":"component---src-templates-content-template-js","path":"/es/part6/estado_complejo_fetch_y_pruebas","result":{"data":{"markdownRemark":{"html":"<div class=\"content\">\n<p>Sigamos ampliando la versión Zustand de la aplicación de notas.</p>\n<p>Para facilitar el desarrollo, cambiemos el estado inicial para que ya contenga algunas notas:</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>Estado más complejo</h3>\n<p>Implementemos el filtrado de las notas que se muestran en la aplicación, permitiendo restringir las notas visibles. El filtro se implementa mediante <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio\">botones de opción</a>:</p>\n<picture><img src=\"/static/a10eaa11ed554b28b204fd0840d62e00/5a190/u1.png\" alt=\"En la parte superior de la página hay un formulario para agregar una nota (campo de entrada y un botón para agregar). Debajo de ese botón de opción, selección de qué notas mostrar, opciones: todas, importantes y no importantes. Debajo de ellas se muestran todas las notas, con el texto importante junto a las notas marcadas como importantes.\" 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>Surge la pregunta de cuál es la mejor forma de gestionar el estado del filtro. Hay dos opciones: crear un store de Zustand separado para el filtro o añadirlo al store existente. Ambas son razonables. Las <a href=\"https://tkdodo.eu/blog/working-with-zustand#keep-the-scope-of-your-store-small\">buenas prácticas</a> recomiendan mantener los elementos que no guardan relación en stores separados. Sin embargo, la lista de notas y el filtro están tan vinculados que colocaremos ambos en el mismo 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>El componente que establece el valor del filtro:</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>El componente <i>App</i> renderiza el filtro:</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>El filtrado de las notas mostradas podría manejarse en el componente <i>NoteList</i>, por ejemplo de la siguiente manera:</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>Se llega a una mejor solución incluyendo la lógica de filtrado directamente en la función <i>useNotes</i> del 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> 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>La función <i>useNotes</i> devuelve siempre una lista de notas filtradas de la forma deseada. El consumidor de la función, el componente <i>NoteList</i>, ni siquiera necesita ser consciente de la existencia del filtro:</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>¡La solución es elegante!</p>\n<blockquote>\n<h4>Una posible solución alternativa</h4>\n<p>Una alternativa sería implementar el filtrado directamente dentro de una función selectora, de modo que tanto las notas como el filtro se lean en una sola llamada <i>useNoteStore</i>:</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>Sin embargo, este enfoque no funciona, ya que conduce a un bucle infinito de renderizado cuando se cambia el filtro.</p>\n<p>El motivo es el siguiente: Zustand compara el valor de retorno del selector utilizando el operador <i>===</i>. Dado que <i>notes.filter(...)</i> crea una nueva array en cada renderizado, React siempre lo interpreta como un nuevo estado y activa otro renderizado, que nuevamente crea una nueva array, y así sucesivamente.</p>\n<p>La solución consiste en añadir <a href=\"https://zustand.docs.pmnd.rs/reference/hooks/use-shallow\">useShallow</a>, que sustituye la comparación <i>===</i> por una comparación superficial: compara uno a uno los elementos del array. Si el contenido no ha cambiado, devuelve la referencia anterior en lugar de crear una nueva, por lo que React considera estable el estado y no vuelve a renderizar.</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>La solución funciona, pero es un poco más difícil de entender. En el material del curso utilizamos la versión presentada anteriormente con dos llamadas <i>useNoteStore</i> independientes.</p>\n</blockquote>\n<p>El código actual de la aplicación está disponible en su totalidad en <a href=\"https://github.com/fullstack-hy2020/zustand-notes/tree/part6-3\">GitHub</a>, en la rama <i>part6-3</i>.</p>\n</div>\n<div class=\"tasks\">\n<h3>Ejercicio 6.6</h3>\n<p>Sigamos con la aplicación de anécdotas.</p>\n<h4>6.6 anécdotas, paso 5</h4>\n<p>Implementar filtrado de las anécdotas mostradas en la aplicación:</p>\n<picture><img src=\"/static/1665ded20b15958ef98ad6e92a140fd9/5a190/u3.png\" alt=\"Se agrega un campo de texto en la parte superior; al escribirlo, las anécdotas mostradas se pueden limitar a aquellas que contienen la cadena escrita en el campo de filtro\" 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>Crea un componente <i>Filter</i> para mostrar el filtro en la pantalla. Puedes utilizar lo siguiente como punto de partida:</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>Datos al servidor</h3>\n<p>Extendamos la aplicación para que las notas se almacenen en un backend. Utilizaremos el <a href=\"/es/part2/obteniendo_datos_del_servidor\">JSON Server</a> que conocemos de la parte 2.</p>\n<p>Guarde el estado inicial de la base de datos en el archivo <i>db.json</i> en la raíz del proyecto:</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>Instalar el servidor JSON:</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>y agregue la siguiente línea a la sección <i>scripts</i> de <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>Inicie el servidor JSON con el comando <em>npm run server</em>.</p>\n<h3>Fetch API</h3>\n<p>En el desarrollo de software, a menudo hay que considerar si implementar una determinada característica utilizando una librería externa o aprovechar las soluciones nativas proporcionadas por el entorno. Ambos enfoques tienen sus propias ventajas y desafíos.</p>\n<p>En partes anteriores del curso hemos utilizado la librería <a href=\"https://axios-http.com/docs/intro\">Axios</a> para realizar solicitudes HTTP. Veamos ahora una alternativa basada en la <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API\">Fetch API</a> nativa.</p>\n<p>Es típico que una librería externa como <i>Axios</i> se implemente utilizando otras librerías externas. Por ejemplo, si instala Axios en un proyecto con el comando <i>npm install axios</i>, la salida de la consola es:</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>Por lo tanto, el comando instalaría no solo la librería de Axios sino también más de 20 paquetes npm más que Axios necesita para funcionar.</p>\n<p>La <i>Fetch API</i> permite realizar solicitudes HTTP de forma similar a Axios, pero sin instalar librerías externas. Mantener una aplicación resulta más sencillo cuando hay menos librerías que actualizar y la seguridad también mejora al reducirse su superficie de ataque potencial. La seguridad y el mantenimiento se tratan en la <a href=\"/es/part7/miscelanea#seguridad-en-aplicaciones-reactnode\">parte 7</a> del curso.</p>\n<p>En la práctica, la realización de solicitudes se realiza mediante la función <i>fetch()</i>. La sintaxis utilizada tiene algunas diferencias respecto a Axios. Pronto también notaremos que Axios se encargó de algunas cosas por nosotros y nos hizo la vida más fácil. Sin embargo, ahora usaremos la API Fetch porque es una solución nativa ampliamente utilizada con la que todo desarrollador Full Stack debería estar familiarizado.</p>\n<h3>Obtención de datos del servidor</h3>\n<p>Creemos una función que obtenga datos del backend en el archivo <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>Veamos más de cerca la implementación de la función <i>getAll</i>. Las notas ahora se obtienen del backend llamando a la función <i>fetch()</i>, a la que se le ha dado la URL del backend como argumento. El tipo de solicitud no se especifica por separado, por lo que <i>fetch</i> realiza la acción predeterminada, que es una solicitud GET.</p>\n<p>Cuando llega la respuesta, comprobamos si la solicitud se realizó correctamente mirando el campo <i>response.ok</i> y arrojamos un error si es necesario:</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>El atributo <i>response.ok</i> obtiene el valor <i>true</i> si la solicitud se realizó correctamente, es decir, si el código de estado de respuesta está en el rango 200-299. Para todos los demás códigos de estado, como 404 o 500, obtiene el valor <i>false</i>.</p>\n<p>Ten en cuenta que <i>fetch</i> no genera automáticamente un error aunque el código de estado de la respuesta sea, por ejemplo, 404. El manejo de errores debe implementarse manualmente, como acabamos de hacer.</p>\n<p>Si la solicitud tuvo éxito, los datos contenidos en la respuesta se convierten al formato JSON:</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> no convierte automáticamente los datos que puedan acompañar a la respuesta al formato JSON; la conversión debe realizarse manualmente. También vale la pena señalar que <i>response.json()</i> es una función asincrónica, por lo que se debe usar la palabra clave <i>await</i> con ella.</p>\n<p>Simplifiquemos un poco el código devolviendo los datos devueltos por la función <i>response.json()</i> directamente:</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>Agreguemos una función al store que se puede usar para inicializar el estado con notas obtenidas del servidor:</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>Implementemos la inicialización de notas en el componente <i>App</i>; como es habitual al recuperar datos de un servidor, utilizamos el hook <i>useEffect</i>:</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>Por lo tanto, las notas se obtienen del servidor usando la función <i>getAll()</i> que definimos y luego se almacenan usando la función <i>initialize</i> del store. Estas acciones se realizan en el hook <i>useEffect</i>, lo que significa que se ejecutan durante el primer renderizado del componente de la aplicación.</p>\n<p>Veamos un pequeño detalle. Hemos añadido la función <i>initialize</i> al array de dependencias del hook <i>useEffect</i>. Si intentamos utilizar un array de dependencias vacío, ESLint muestra la advertencia <i>React Hook useEffect has a missing dependency: 'initialize'</i>. ¿Qué está ocurriendo?</p>\n<p>El código funcionaría igual aunque utilizáramos un array de dependencias vacío, porque <i>initialize</i> hace referencia a la misma función durante toda la ejecución. Sin embargo, es una buena práctica incluir como dependencias todas las variables y funciones utilizadas por <em>useEffect</em> que estén definidas dentro del componente. Esto ayuda a evitar errores inesperados.</p>\n<h3>Envío de datos al servidor</h3>\n<p>A continuación, implementemos la funcionalidad para enviar una nueva nota al servidor. Al mismo tiempo podemos practicar cómo realizar una solicitud POST usando la función <i>fetch()</i>.</p>\n<p>Extendamos el código de comunicación del servidor en <i>src/services/notes.js</i> de la siguiente manera:</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>Veamos más de cerca la implementación de la función <i>createNew</i>. El primer parámetro de la función <i>fetch()</i> especifica la URL a la que se realiza la solicitud. El segundo parámetro es un objeto que define los demás detalles de la solicitud, como el tipo de solicitud, los encabezados y los datos enviados con la solicitud. Podemos aclarar aún más el código almacenando el objeto que define los detalles de la solicitud en una variable auxiliar <i>options</i> separada:</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>Miremos más de cerca el objeto <i>options</i>:</p>\n<ul>\n<li><i>method</i> define el tipo de solicitud, que en este caso es <i>POST</i></li>\n<li><i>headers</i> define los encabezados de solicitud. Adjuntamos el encabezado <i>'Content-Type': 'application/json'</i> a la solicitud para que el servidor sepa que los datos incluidos con la solicitud están en formato JSON y pueda manejar la solicitud correctamente.</li>\n<li><i>body</i> contiene los datos que se enviarán con la solicitud. El campo no puede contener directamente un objeto JavaScript; primero debe convertirse en una cadena JSON llamando a <i>JSON.stringify()</i>.</li>\n</ul>\n<p>Al igual que con la solicitud GET, aquí también verificamos el código de estado de respuesta para detectar errores:</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>Si la solicitud tiene éxito, <i>JSON Server</i> devuelve la nota recién creada, para la cual también generó un <i>id</i> único. Los datos contenidos en la respuesta aún deben convertirse al formato JSON usando la función <i>response.json()</i>:</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>Luego cambiemos el componente <i>NoteForm</i> de nuestra aplicación para que se envíe una nueva nota al backend. La función <i>addNote</i> del componente cambia ligeramente:</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>Cuando se crea una nueva nota en el backend llamando a la función <i>createNew()</i>, obtenemos un objeto que describe la nota, para la cual el backend ha generado un <i>id</i>.</p>\n<p>El código actual de la aplicación está disponible en su totalidad en <a href=\"https://github.com/fullstack-hy2020/zustand-notes/tree/part6-4\">GitHub</a>, en la rama <i>part6-4</i>.</p>\n<h3>Acciones asíncronas</h3>\n<p>Nuestro enfoque es bastante bueno, pero en cierto sentido desafortunado, ya que la comunicación con el servidor ocurre dentro del código de las funciones que definen los componentes. Sería mejor si la comunicación pudiera abstraerse de los componentes, de modo que solo necesiten llamar a una función apropiada que proporciona el store.</p>\n<p>Queremos que <i>App</i> inicialice el estado de la aplicación de la siguiente manera:</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> a su vez crea una nueva nota como esta:</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>El cambio a <i>store.js</i> es el siguiente:</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>Las funciones <i>add</i> y <i>initialize</i> se han convertido en funciones asincrónicas, que primero llaman a la función noteService adecuada y luego actualizan el estado.</p>\n<p>La solución es elegante; La gestión del estado y la comunicación con el servidor están completamente separadas fuera de los componentes de React.</p>\n<p>Finalicemos la aplicación sincronizando el cambio de importancia con el servidor.</p>\n<p><i>noteService.js</i> se amplía de la siguiente manera:</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>El cambio a la función <i>toggleImportance</i> del store es el siguiente:</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>Hay un detalle digno de mención en la nueva función. La función recibe el id de la nota como parámetro. Sin embargo, la nota modificada debe enviarse al backend. Se puede encontrar llamando a la función <i>getState</i> del store:</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>Los stores de Zustand también tienen otras <a href=\"https://zustand.docs.pmnd.rs/reference/apis/create#returns\">funciones auxiliares</a>, que pueden resultar útiles en algunas situaciones.</p>\n<p>Sin embargo, cambiemos también la definición del store para que también pasemos el parámetro <i>get</i> a la función dada a <i>create</i>, a través de la cual podemos acceder a los valores de estado cuando sea necesario:</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>La función <i>get</i> devuelve el estado actual del store. Por ejemplo, la llamada <i>get().notes</i> proporciona las notas actuales del store. La función <i>get</i> es funcionalmente equivalente a llamar a <i>useNoteStore.getState()</i>, pero es la forma más idiomática de referirse al estado del store desde las propias funciones del store.</p>\n<p>El código de la aplicación está en <a href=\"https://github.com/fullstack-hy2020/zustand-notes/tree/part6-5\">GitHub</a> en la rama <i>part6-5</i>.</p>\n</div>\n<div class=\"tasks\">\n<h3>Ejercicios 6.7.-6.11.</h3>\n<h4>6.7 anécdotas, paso 6</h4>\n<p>Obtén las anécdotas del backend de JSON Server cuando se inicie la aplicación. Utiliza la Fetch API para realizar la solicitud HTTP.</p>\n<p>Puedes encontrar contenido inicial para el backend <a href=\"https://github.com/fullstack-hy2020/misc/blob/master/anecdotes.json\">aquí</a>.</p>\n<h4>6.8 anécdotas, paso 7</h4>\n<p>Modifica la creación de nuevas anécdotas para que se almacenen en el backend. Utiliza la Fetch API en tu implementación.</p>\n<h4>6.9 anécdotas, paso 8</h4>\n<p>La votación aún no guarda los cambios en el backend. Arreglar la situación.</p>\n<h4>6.10 anécdotas, paso 9</h4>\n<p>La aplicación tiene un esqueleto listo para usar para el componente <i>Notification</i>:</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>Amplíe la aplicación para que muestre una notificación utilizando el componente <i>Notification</i> durante cinco segundos cuando se votan anécdotas o se crean nuevas anécdotas:</p>\n<picture><img src=\"/static/c4f460152b68a605ba70ae47ef09301e/5a190/8eb.png\" alt=\"Se muestra una notificación al votar: votaste &#x27;si te duele, hazlo más seguido&#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>Utiliza Zustand para gestionar el estado de las notificaciones. Puede ser conveniente crear un store de Zustand separado para ellas, ya que su uso podría extenderse a otras áreas a medida que la aplicación crezca, como el inicio de sesión.</p>\n<h4>6.11 anécdotas, paso 10</h4>\n<p>Notamos que algunas de las anécdotas añadidas por los usuarios no son muy buenas. Implementar una característica que permita eliminar anécdotas que tengan cero votos.</p>\n</div>\n<div class=\"content\">\n<h3>Middlewares</h3>\n<p>Al desarrollar una aplicación, a menudo nos encontramos con situaciones en las que es difícil entender por qué la aplicación se comporta de forma inesperada. El estado cambia como resultado de alguna llamada a una función de acción, pero no está claro qué llamada cambió qué y en qué orden. El registro tradicional de funciones individuales en la consola sólo ayuda de forma limitada.</p>\n<p>Zustand admite los llamados middlewares, que se pueden utilizar para agregar funcionalidad a los stores de forma transparente, sin tocar la propia lógica del store. La idea del middleware es simple: \"envuelve\" el store y puede, por ejemplo, registrar automáticamente cada cambio de estado.</p>\n<p>La forma de las funciones del middleware es algo críptica. A continuación se muestra un <i>logger</i> que siempre imprime el estado antiguo y nuevo del store cada vez que cambia el estado:</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>El middleware se activa \"envolviendo\" la función dada al <i>create</i> de Zustand como parámetro:</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>Ahora, cada vez que cambia el estado del store, siempre podemos ver en la consola cómo cambia el estado:</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>En la práctica, nuestro middleware definido funciona reemplazando la función original <i>set</i> con la función</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>que además de llamar a <i>set</i>, también imprime el estado antiguo y nuevo (accesible a través de la función <i>get</i>) en la consola. El segundo parámetro es el antiguo <i>get</i> sin cambios.</p>\n<p>Zustand también tiene un middleware <i>devtools</i> listo para usar que integra el store con la extensión <a href=\"https://chromewebstore.google.com/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd\">Redux DevTools</a> del navegador. Devtools es una herramienta de desarrollo extremadamente útil, ya que le permite realizar un seguimiento visual de los cambios de estado.</p>\n<p>La configuración es sencilla:</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>Cuando la extensión Redux DevTools está instalada en el navegador, el estado del store y sus cambios se pueden inspeccionar en las herramientas de desarrollo del navegador:</p>\n<picture><img src=\"/static/9d3b0d250c37dab1dd5d32a163cd6035/5a190/u6.png\" alt=\"Vista de Redux DevTools en el navegador: a la izquierda una lista de cambios de estado, a la derecha el contenido del estado en forma de árbol\" 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>Pruebas de los stores de Zustand</h3>\n<p>Finalmente, veamos cómo probar los stores de Zustand con Vitest.</p>\n<p>Para simplificar, comencemos con el store del contador:</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>Agregamos una exportación a la definición de las pruebas, a través de la cual la prueba puede acceder al store.</p>\n<p>Instalemos 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>Implementemos la prueba en el archivo <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>Las pruebas son bastante sencillas y utilizan la función <a href=\"https://zustand.docs.pmnd.rs/reference/apis/create#returns\">getState</a> del store, que les permite leer el estado del store y ejecutar las funciones del store.</p>\n<p>Antes de cada prueba, el store se restablece a su estado inicial en el bloque <i>beforeEach</i> usando la función <a href=\"https://zustand.docs.pmnd.rs/reference/apis/create#returns\">setState</a> del store.</p>\n<p>En nuestro caso, restablecer el store a su estado inicial es sencillo, aunque no siempre lo es. La <a href=\"https://zustand.docs.pmnd.rs/learn/guides/testing#vitest\">documentación de Zustand</a> describe cómo crear una versión de los stores para las pruebas que se restablece automáticamente antes de cada una. Sin embargo, el método es lo bastante complejo e innecesario para nuestro caso como para omitirlo por ahora.</p>\n<p>Por tanto, las pruebas utilizan el store directamente. Si se ha implementado una lógica más compleja mediante hooks personalizados, puede ser necesario escribir pruebas que también los utilicen. En el contador se accede al store mediante los hooks <i>useCounter</i> y <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>En este caso, los hooks no contienen ninguna lógica, simplemente exponen por separado el valor almacenado en el store y las funciones del store. Por lo tanto, el método de prueba que utilizamos anteriormente es perfectamente correcto.</p>\n<p>Sin embargo, hagamos otra versión de las pruebas a modo de ejemplo, donde el store se usa exactamente de la misma manera que la aplicación.</p>\n<p><i>useCounter</i> y <i>useCounterControls</i> son hooks de React, por lo que probarlos requiere la <a href=\"https://github.com/testing-library/react-testing-library\">Librería de prueba de React</a> y la librería <a href=\"https://github.com/jsdom/jsdom\">jsdom</a>:</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>Agreguemos la configuración del entorno de prueba a <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>Las pruebas son las siguientes:</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>Hay algunas cosas interesantes en la prueba. Al comienzo de las pruebas, los hooks se representan usando la función <a href=\"https://testing-library.com/docs/react-testing-library/api/#renderhook\">renderHook</a>:</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>De esta forma la prueba obtiene acceso a los valores devueltos por los hooks, que se almacenan en las variables <i>counter</i> y <i>controls</i>.</p>\n<p>Los hooks se llaman envolviendo la llamada dentro de la función <a href=\"https://testing-library.com/docs/react-testing-library/api/#act\">act</a>:</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>Finalmente, se produce la expectativa de la prueba:</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>Como podemos ver, para acceder al hook en sí aún necesitamos tomar el campo <i>current</i> del objeto devuelto por <i>renderHook</i>, que corresponde al valor actual del hook.</p>\n<blockquote>\n<h4>¿Qué es acto?</h4>\n<p><i>act</i> es una función auxiliar que garantiza que todas las actualizaciones de estado y sus efectos secundarios se hayan procesado antes de que continúe el código de prueba.</p>\n<p>Cuando se produce un cambio de estado en un componente o enlace de React, React no actualiza el estado inmediatamente sino que pone las actualizaciones en cola. act obliga a ejecutar estas actualizaciones en cola.</p>\n<p>Sin actuar, una prueba podría verificar el estado antes de que React haya tenido tiempo de actualizarlo, lo que provocaría que la prueba falle o dé resultados incorrectos.</p>\n<p>La librería de pruebas de React incluye muchas de sus funciones (como fireEvent, userEvent) automáticamente, pero cuando se prueban enlaces directamente, generalmente es necesario.</p>\n</blockquote>\n<p>Las pruebas mediante hooks utilizan la librería de pruebas de React y representan los hooks en un contexto real de React usando jsdom. Este enfoque es considerablemente más lento que las pruebas que utilizan el store directamente, por lo que si los enlaces no contienen lógica compleja, puede ser suficiente ejecutar las pruebas utilizando el store directamente.</p>\n<p>El código que contiene las pruebas de contador de Zustand está disponible en <a href=\"https://github.com/fullstack-hy2020/zustand-counter\">GitHub</a>.</p>\n<h3>Pruebas del store de notas</h3>\n<p>Probar el store de la aplicación de notas es un caso algo más desafiante, ya que el store contiene funciones asincrónicas que llaman al servidor:</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>Esta vez <i>useNotes</i> también contiene una cantidad significativa de lógica, por lo que las pruebas probablemente deberían realizarse mediante enlaces con la librería de pruebas React.</p>\n<p>Instalemos las librerías necesarias:</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>Agreguemos la configuración del entorno de prueba a <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>La primera parte de las pruebas es la siguiente:</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>Hay mucho que digerir en las pruebas. Las pruebas crean, usando Vitest, una versión <a href=\"https://vitest.dev/guide/mocking\">simulada</a> del <i>noteService</i> responsable de comunicarse con el servidor:</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> reemplaza el <i>noteService</i> en el módulo <i>./services/notes</i> con su propia versión, donde todas las funciones se reemplazan con funciones simuladas devueltas por <a href=\"https://vitest.dev/api/vi.html#vi-fn\">vi.fn</a>.</p>\n<p>Antes de cada prueba, el store se restablece a su estado inicial y se borran las funciones simuladas:</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>Al comienzo de cada prueba, al <i>noteService</i> simulado se le indica a través de la función <a href=\"https://vitest.dev/api/mock.html#mockresolvedvalue\">mockResolvedValue</a> cómo debe comportarse en el contexto de la prueba:</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>Primero, la prueba establece que, cuando se llama a <i>noteService.getAll</i>, se devuelven al store las notas del array <i>mockNotes</i>.</p>\n<p>Lo que se está probando es la llamada a la función <i>initialize</i>:</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>Dado que se trata de una función asincrónica, se debe esperar la finalización de la llamada con la palabra clave <i>await</i>.</p>\n<p>Finalmente, la prueba verifica que el estado del store contiene la misma lista de notas que devolvió la función simulada <i>noteService.getAll</i>:</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>Las otras pruebas siguen el mismo patrón: primero, se define lo que devuelve la función llamada <i>noteService</i> del store y luego se ejecuta la prueba real.</p>\n<p>La segunda parte de las pruebas verifica que el filtrado funciona correctamente:</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>El estado se inicializa con dos notas, una de las cuales es importante y la otra no. Los tres casos de prueba verifican que <i>useNotes</i> devuelva las notas correctas para todos los valores de filtro.</p>\n<p>El código final de la aplicación está en <a href=\"https://github.com/fullstack-hy2020/zustand-notes/tree/part6-6\">GitHub</a> en la rama <i>part6-6</i>.</p>\n</div>\n<div class=\"tasks\">\n<h3>Ejercicios 6.12.-6.15.</h3>\n<h4>6.12 Anécdotas, paso 11</h4>\n<p>Escribe una prueba que compruebe que el estado se inicializa con las anécdotas devueltas por el backend.</p>\n<h4>6.13 Anécdotas, paso 12</h4>\n<p>Escribe una prueba que compruebe que el componente que muestra las anécdotas las recibe del store ordenadas por votos.</p>\n<h4>6.14 Anécdotas, paso 13</h4>\n<p>Escribe una prueba que compruebe que el componente de React adecuado recibe una lista de anécdotas correctamente filtrada.</p>\n<h4>6.15 Anécdotas, paso 14</h4>\n<p>Escribe una prueba que verifique que votar aumenta el número de votos para una anécdota.</p>\n</div>","frontmatter":{"mainImage":{"publicURL":"/static/a3b7bc3fafcb5b47227616e1343970e5/part-6.svg"},"part":6,"letter":"b","lang":"es"}}},"pageContext":{"part":6,"letter":"b","lang":"es"}},"staticQueryHashes":["3128451518"]}