File size: 76,414 Bytes
9375fc1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | <!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>docs/api/hooks/async-hooks | react-declarative</title><meta name="description" content="Documentation for react-declarative"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">react-declarative</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">react-declarative</a></li><li><a href="docs_api_hooks_async-hooks.html">docs/api/hooks/async-hooks</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="async-hooks-usesinglerunaction-usequeuedaction-and-more" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Async hooks: useSinglerunAction, useQueuedAction, and more<a href="#async-hooks-usesinglerunaction-usequeuedaction-and-more" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><p>Async hooks give you a consistent way to handle asynchronous operations in your components. Each hook returns a <code>loading</code> boolean and an <code>error</code> boolean alongside an <code>execute</code> function, so you can drive UI state without writing boilerplate. Depending on which hook you choose, you get additional behavior: single-execution guards, ordered queuing, batch progress tracking, or a shared semaphore that disables multiple buttons at once.</p>
<a id="usesinglerunaction" class="tsd-anchor"></a><h2 class="tsd-anchor-link">useSinglerunAction<a href="#usesinglerunaction" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Wraps an async function so that <strong>only one invocation can run at a time</strong>. If you call <code>execute</code> while a previous call is still pending, the new call is a no-op until the first one settles. This is useful for upload buttons and any action where duplicate submissions would cause problems.</p>
<a id="signature" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Signature<a href="#signature" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="ts"><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-5">useSinglerunAction</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1">, </span><span class="hl-7">Payload</span><span class="hl-1">>(</span><br/><span class="hl-1"> </span><span class="hl-5">run</span><span class="hl-1">: (</span><span class="hl-2">payload</span><span class="hl-1">: </span><span class="hl-7">Payload</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">Data</span><span class="hl-1"> | </span><span class="hl-7">Promise</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1">>,</span><br/><span class="hl-1"> </span><span class="hl-2">options</span><span class="hl-1">?: {</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadStart</span><span class="hl-1">?: () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadEnd</span><span class="hl-1">?: (</span><span class="hl-2">isOk</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">fallback</span><span class="hl-1">?: (</span><span class="hl-2">e</span><span class="hl-1">: </span><span class="hl-7">Error</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">throwError</span><span class="hl-1">?: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">): {</span><br/><span class="hl-1"> </span><span class="hl-5">execute</span><span class="hl-1">: (</span><span class="hl-2">payload</span><span class="hl-1">?: </span><span class="hl-7">Payload</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">Promise</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1"> | </span><span class="hl-7">null</span><span class="hl-1">>;</span><br/><span class="hl-1"> </span><span class="hl-2">loading</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">error</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<a id="parameters" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Parameters<a href="#parameters" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong><code>run</code></strong> <em>(required)</em> — <code>(payload: Payload) => Data | Promise<Data></code></p>
<p>The async function to execute. Receives an optional <code>payload</code> argument and must return the result or a Promise of the result.</p>
<p><strong><code>options.onLoadStart</code></strong> — <code>() => void</code></p>
<p>Called immediately before the action begins executing. Use this to show a global loader.</p>
<p><strong><code>options.onLoadEnd</code></strong> — <code>(isOk: boolean) => void</code></p>
<p>Called after the action completes or fails. <code>isOk</code> is <code>false</code> when an error was thrown.</p>
<p><strong><code>options.fallback</code></strong> — <code>(e: Error) => void</code></p>
<p>Called with the caught error when the action throws and <code>throwError</code> is <code>false</code> (the default). Use this to display an error toast.</p>
<p><strong><code>options.throwError</code></strong> — <code>boolean</code> <em>(default: <code>false</code>)</em></p>
<p>When <code>true</code>, errors thrown inside <code>run</code> are re-thrown from <code>execute</code> instead of being passed to <code>fallback</code>.</p>
<a id="return-value" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Return value<a href="#return-value" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><table>
<thead>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>execute</code></td>
<td><code>(payload?) => Promise<Data | null></code></td>
<td>Triggers the action. Concurrent calls while loading are silently dropped. Call <code>execute.clear()</code> to reset the single-run lock.</td>
</tr>
<tr>
<td><code>loading</code></td>
<td><code>boolean</code></td>
<td><code>true</code> while the action is running.</td>
</tr>
<tr>
<td><code>error</code></td>
<td><code>boolean</code></td>
<td><code>true</code> if the most recent invocation threw an error.</td>
</tr>
</tbody>
</table>
<a id="usage" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Usage<a href="#usage" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">useSinglerunAction</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">'react-declarative'</span><span class="hl-1">;</span><br/><br/><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-5">UploadButton</span><span class="hl-1">({ </span><span class="hl-2">onChange</span><span class="hl-1"> }: { </span><span class="hl-5">onChange</span><span class="hl-1">: (</span><span class="hl-2">path</span><span class="hl-1">: </span><span class="hl-7">string</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1"> }) {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> { </span><span class="hl-10">execute</span><span class="hl-1">, </span><span class="hl-10">loading</span><span class="hl-1"> } = </span><span class="hl-5">useSinglerunAction</span><span class="hl-1">(</span><span class="hl-4">async</span><span class="hl-1"> () </span><span class="hl-4">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-10">file</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-5">chooseFile</span><span class="hl-1">(</span><span class="hl-3">'image/jpeg,image/png'</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">file</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-10">filePath</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">uploadService</span><span class="hl-1">.</span><span class="hl-5">upload</span><span class="hl-1">(</span><span class="hl-2">file</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-5">onChange</span><span class="hl-1">(</span><span class="hl-2">filePath</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> });</span><br/><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> (</span><br/><span class="hl-1"> </span><span class="hl-6"><</span><span class="hl-18">button</span><span class="hl-1"> </span><span class="hl-8">onClick</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">execute</span><span class="hl-4">}</span><span class="hl-1"> </span><span class="hl-8">disabled</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">loading</span><span class="hl-4">}</span><span class="hl-6">></span><br/><span class="hl-1"> </span><span class="hl-4">{</span><span class="hl-2">loading</span><span class="hl-9"> </span><span class="hl-1">?</span><span class="hl-9"> </span><span class="hl-3">'Uploading…'</span><span class="hl-9"> </span><span class="hl-1">:</span><span class="hl-9"> </span><span class="hl-3">'Upload image'</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6"></</span><span class="hl-18">button</span><span class="hl-6">></span><br/><span class="hl-1"> );</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<hr>
<a id="usequeuedaction" class="tsd-anchor"></a><h2 class="tsd-anchor-link">useQueuedAction<a href="#usequeuedaction" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Runs every call in the order it was received — earlier calls must complete before later ones start. Unlike <code>useSinglerunAction</code>, <strong>no calls are dropped</strong>: they queue up and execute sequentially. This is ideal for real-time state-reducer patterns such as processing WebSocket events in order.</p>
<a id="signature-1" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Signature<a href="#signature-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="ts"><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-5">useQueuedAction</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1">, </span><span class="hl-7">Payload</span><span class="hl-1">>(</span><br/><span class="hl-1"> </span><span class="hl-5">run</span><span class="hl-1">: (</span><span class="hl-2">payload</span><span class="hl-1">: </span><span class="hl-7">Payload</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">Data</span><span class="hl-1"> | </span><span class="hl-7">Promise</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1">>,</span><br/><span class="hl-1"> </span><span class="hl-2">options</span><span class="hl-1">?: {</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadStart</span><span class="hl-1">?: () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadEnd</span><span class="hl-1">?: (</span><span class="hl-2">isOk</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">fallback</span><span class="hl-1">?: (</span><span class="hl-2">e</span><span class="hl-1">: </span><span class="hl-7">Error</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">throwError</span><span class="hl-1">?: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">): {</span><br/><span class="hl-1"> </span><span class="hl-5">execute</span><span class="hl-1">: (</span><span class="hl-2">payload</span><span class="hl-1">?: </span><span class="hl-7">Payload</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">Promise</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1"> | </span><span class="hl-7">null</span><span class="hl-1">>;</span><br/><span class="hl-1"> </span><span class="hl-2">loading</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">error</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<a id="parameters-1" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Parameters<a href="#parameters-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong><code>run</code></strong> <em>(required)</em> — <code>(payload: Payload) => Data | Promise<Data></code></p>
<p>The async function to execute for each queued item.</p>
<p><strong><code>options.onLoadStart</code></strong> — <code>() => void</code></p>
<p>Called before each queued execution begins.</p>
<p><strong><code>options.onLoadEnd</code></strong> — <code>(isOk: boolean) => void</code></p>
<p>Called after each queued execution completes or fails.</p>
<p><strong><code>options.fallback</code></strong> — <code>(e: Error) => void</code></p>
<p>Error handler when <code>throwError</code> is <code>false</code>.</p>
<p><strong><code>options.throwError</code></strong> — <code>boolean</code> <em>(default: <code>false</code>)</em></p>
<p>Re-throws errors from <code>execute</code> instead of routing them to <code>fallback</code>.</p>
<a id="return-value-1" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Return value<a href="#return-value-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><table>
<thead>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>execute</code></td>
<td><code>(payload?) => Promise<Data | null></code></td>
<td>Enqueues a call. Call <code>execute.cancel()</code> to abandon the current item and <code>execute.clear()</code> to drain the entire queue.</td>
</tr>
<tr>
<td><code>loading</code></td>
<td><code>boolean</code></td>
<td><code>true</code> while any item is being processed.</td>
</tr>
<tr>
<td><code>error</code></td>
<td><code>boolean</code></td>
<td><code>true</code> if the most recent item threw.</td>
</tr>
</tbody>
</table>
<a id="usage-1" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Usage<a href="#usage-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">useEffect</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">'react'</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">useQueuedAction</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">'react-declarative'</span><span class="hl-1">;</span><br/><br/><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-5">KanbanBoard</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> { </span><span class="hl-10">execute</span><span class="hl-1"> } = </span><span class="hl-5">useQueuedAction</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-4">async</span><span class="hl-1"> ({ </span><span class="hl-2">type</span><span class="hl-1">, </span><span class="hl-2">payload</span><span class="hl-1"> }) </span><span class="hl-4">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">type</span><span class="hl-1"> === </span><span class="hl-3">'create'</span><span class="hl-1">) </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">api</span><span class="hl-1">.</span><span class="hl-5">createCard</span><span class="hl-1">(</span><span class="hl-2">payload</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">type</span><span class="hl-1"> === </span><span class="hl-3">'update'</span><span class="hl-1">) </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">api</span><span class="hl-1">.</span><span class="hl-5">updateCard</span><span class="hl-1">(</span><span class="hl-2">payload</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">type</span><span class="hl-1"> === </span><span class="hl-3">'remove'</span><span class="hl-1">) </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">api</span><span class="hl-1">.</span><span class="hl-5">removeCard</span><span class="hl-1">(</span><span class="hl-2">payload</span><span class="hl-1">);</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadStart</span><span class="hl-2">:</span><span class="hl-1"> () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-5">setAppbarLoader</span><span class="hl-1">(</span><span class="hl-4">true</span><span class="hl-1">),</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadEnd</span><span class="hl-2">:</span><span class="hl-1"> () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-5">setAppbarLoader</span><span class="hl-1">(</span><span class="hl-4">false</span><span class="hl-1">),</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> );</span><br/><br/><span class="hl-1"> </span><span class="hl-5">useEffect</span><span class="hl-1">(() </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-2">kanbanService</span><span class="hl-1">.</span><span class="hl-2">createSubject</span><span class="hl-1">.</span><span class="hl-5">subscribe</span><span class="hl-1">(</span><span class="hl-2">execute</span><span class="hl-1">), []);</span><br/><span class="hl-1"> </span><span class="hl-5">useEffect</span><span class="hl-1">(() </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-2">kanbanService</span><span class="hl-1">.</span><span class="hl-2">updateSubject</span><span class="hl-1">.</span><span class="hl-5">subscribe</span><span class="hl-1">(</span><span class="hl-2">execute</span><span class="hl-1">), []);</span><br/><span class="hl-1"> </span><span class="hl-5">useEffect</span><span class="hl-1">(() </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-2">kanbanService</span><span class="hl-1">.</span><span class="hl-2">removeSubject</span><span class="hl-1">.</span><span class="hl-5">subscribe</span><span class="hl-1">(</span><span class="hl-2">execute</span><span class="hl-1">), []);</span><br/><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> </span><span class="hl-6"><</span><span class="hl-7">Board</span><span class="hl-1"> </span><span class="hl-6">/></span><span class="hl-1">;</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<hr>
<a id="useasyncaction" class="tsd-anchor"></a><h2 class="tsd-anchor-link">useAsyncAction<a href="#useasyncaction" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>The foundational async hook. Every call to <code>execute</code> <strong>cancels the previous in-flight call</strong> and starts a fresh one. Use this when you want the latest request to always win — for example, live search or on-demand data loads triggered by user interactions.</p>
<a id="signature-2" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Signature<a href="#signature-2" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="ts"><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-5">useAsyncAction</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1">, </span><span class="hl-7">Payload</span><span class="hl-1">>(</span><br/><span class="hl-1"> </span><span class="hl-5">run</span><span class="hl-1">: (</span><span class="hl-2">payload</span><span class="hl-1">: </span><span class="hl-7">Payload</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">Data</span><span class="hl-1"> | </span><span class="hl-7">Promise</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1">>,</span><br/><span class="hl-1"> </span><span class="hl-2">options</span><span class="hl-1">?: {</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadStart</span><span class="hl-1">?: () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadEnd</span><span class="hl-1">?: (</span><span class="hl-2">isOk</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">fallback</span><span class="hl-1">?: (</span><span class="hl-2">e</span><span class="hl-1">: </span><span class="hl-7">Error</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">throwError</span><span class="hl-1">?: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">): {</span><br/><span class="hl-1"> </span><span class="hl-5">execute</span><span class="hl-1">: (</span><span class="hl-2">payload</span><span class="hl-1">?: </span><span class="hl-7">Payload</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">Promise</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1"> | </span><span class="hl-7">null</span><span class="hl-1">>;</span><br/><span class="hl-1"> </span><span class="hl-2">loading</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">error</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<a id="parameters-2" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Parameters<a href="#parameters-2" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong><code>run</code></strong> <em>(required)</em> — <code>(payload: Payload) => Data | Promise<Data></code></p>
<p>The async function to run. The previous invocation is cancelled when a new <code>execute</code> call arrives.</p>
<p><strong><code>options.onLoadStart</code></strong> — <code>() => void</code></p>
<p>Called before each execution.</p>
<p><strong><code>options.onLoadEnd</code></strong> — <code>(isOk: boolean) => void</code></p>
<p>Called after each execution.</p>
<p><strong><code>options.fallback</code></strong> — <code>(e: Error) => void</code></p>
<p>Error handler when <code>throwError</code> is <code>false</code>.</p>
<p><strong><code>options.throwError</code></strong> — <code>boolean</code> <em>(default: <code>false</code>)</em></p>
<p>Re-throws errors from <code>execute</code>.</p>
<a id="return-value-2" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Return value<a href="#return-value-2" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><table>
<thead>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>execute</code></td>
<td><code>(payload?) => Promise<Data | null></code></td>
<td>Triggers the action, cancelling any previous pending call.</td>
</tr>
<tr>
<td><code>loading</code></td>
<td><code>boolean</code></td>
<td><code>true</code> while the current call is running.</td>
</tr>
<tr>
<td><code>error</code></td>
<td><code>boolean</code></td>
<td><code>true</code> if the most recent call threw.</td>
</tr>
</tbody>
</table>
<a id="usage-2" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Usage<a href="#usage-2" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">useAsyncAction</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">'react-declarative'</span><span class="hl-1">;</span><br/><br/><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-5">SaveButton</span><span class="hl-1">({ </span><span class="hl-2">data</span><span class="hl-1"> }: { </span><span class="hl-2">data</span><span class="hl-1">: </span><span class="hl-7">FormData</span><span class="hl-1"> }) {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> { </span><span class="hl-10">execute</span><span class="hl-1">, </span><span class="hl-10">loading</span><span class="hl-1">, </span><span class="hl-10">error</span><span class="hl-1"> } = </span><span class="hl-5">useAsyncAction</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-4">async</span><span class="hl-1"> (</span><span class="hl-2">formData</span><span class="hl-1">: </span><span class="hl-7">FormData</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">api</span><span class="hl-1">.</span><span class="hl-5">save</span><span class="hl-1">(</span><span class="hl-2">formData</span><span class="hl-1">);</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">fallback</span><span class="hl-2">:</span><span class="hl-1"> (</span><span class="hl-2">e</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-2">toast</span><span class="hl-1">.</span><span class="hl-5">error</span><span class="hl-1">(</span><span class="hl-2">e</span><span class="hl-1">.</span><span class="hl-2">message</span><span class="hl-1">),</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> );</span><br/><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> (</span><br/><span class="hl-1"> </span><span class="hl-6"><></span><br/><span class="hl-1"> </span><span class="hl-4">{</span><span class="hl-2">error</span><span class="hl-9"> </span><span class="hl-1">&&</span><span class="hl-9"> </span><span class="hl-6"><</span><span class="hl-18">span</span><span class="hl-6">></span><span class="hl-9">Save failed — please try again.</span><span class="hl-6"></</span><span class="hl-18">span</span><span class="hl-6">></span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6"><</span><span class="hl-18">button</span><span class="hl-1"> </span><span class="hl-8">onClick</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-9">() </span><span class="hl-4">=></span><span class="hl-9"> </span><span class="hl-5">execute</span><span class="hl-9">(</span><span class="hl-2">data</span><span class="hl-9">)</span><span class="hl-4">}</span><span class="hl-1"> </span><span class="hl-8">disabled</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">loading</span><span class="hl-4">}</span><span class="hl-6">></span><br/><span class="hl-1"> Save</span><br/><span class="hl-1"> </span><span class="hl-6"></</span><span class="hl-18">button</span><span class="hl-6">></span><br/><span class="hl-1"> </span><span class="hl-6"></></span><br/><span class="hl-1"> );</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<hr>
<a id="useasyncprogress" class="tsd-anchor"></a><h2 class="tsd-anchor-link">useAsyncProgress<a href="#useasyncprogress" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Processes a <strong>batch of items sequentially</strong> while tracking progress as a percentage (0–100). Each item in the array is processed one at a time; the hook exposes the current progress value and any per-item errors that accumulated. Feed the <code>progress</code> value directly into a <code><LinearProgress /></code> component.</p>
<a id="signature-3" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Signature<a href="#signature-3" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="ts"><span class="hl-4">interface</span><span class="hl-1"> </span><span class="hl-7">IProcess</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1">> {</span><br/><span class="hl-1"> </span><span class="hl-2">label</span><span class="hl-1">: </span><span class="hl-7">string</span><span class="hl-1">; </span><span class="hl-17">// human-readable identifier shown while processing</span><br/><span class="hl-1"> </span><span class="hl-2">data</span><span class="hl-1">: </span><span class="hl-7">Data</span><span class="hl-1">; </span><span class="hl-17">// the payload passed to your process function</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-5">useAsyncProgress</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1">, </span><span class="hl-7">Result</span><span class="hl-1"> = </span><span class="hl-7">void</span><span class="hl-1">>(</span><br/><span class="hl-1"> </span><span class="hl-5">process</span><span class="hl-1">: (</span><span class="hl-2">item</span><span class="hl-1">: </span><span class="hl-7">IProcess</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1">>) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">Result</span><span class="hl-1"> | </span><span class="hl-7">Promise</span><span class="hl-1"><</span><span class="hl-7">Result</span><span class="hl-1">>,</span><br/><span class="hl-1"> </span><span class="hl-2">options</span><span class="hl-1">?: {</span><br/><span class="hl-1"> </span><span class="hl-2">delay</span><span class="hl-1">?: </span><span class="hl-7">number</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onBegin</span><span class="hl-1">?: () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onEnd</span><span class="hl-1">?: (</span><span class="hl-2">isOk</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onFinish</span><span class="hl-1">?: (</span><br/><span class="hl-1"> </span><span class="hl-2">data</span><span class="hl-1">: </span><span class="hl-7">Data</span><span class="hl-1">[],</span><br/><span class="hl-1"> </span><span class="hl-2">errors</span><span class="hl-1">: { </span><span class="hl-2">label</span><span class="hl-1">: </span><span class="hl-7">string</span><span class="hl-1">; </span><span class="hl-2">message</span><span class="hl-1">: </span><span class="hl-7">string</span><span class="hl-1">; </span><span class="hl-2">error</span><span class="hl-1">: </span><span class="hl-7">Error</span><span class="hl-1"> }[],</span><br/><span class="hl-1"> </span><span class="hl-2">results</span><span class="hl-1">: (</span><span class="hl-7">Result</span><span class="hl-1"> | </span><span class="hl-7">null</span><span class="hl-1">)[]</span><br/><span class="hl-1"> ) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onError</span><span class="hl-1">?: (</span><span class="hl-2">errors</span><span class="hl-1">: { </span><span class="hl-2">label</span><span class="hl-1">: </span><span class="hl-7">string</span><span class="hl-1">; </span><span class="hl-2">message</span><span class="hl-1">: </span><span class="hl-7">string</span><span class="hl-1">; </span><span class="hl-2">error</span><span class="hl-1">: </span><span class="hl-7">Error</span><span class="hl-1"> }[]) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1"> | </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onProgress</span><span class="hl-1">?: (</span><span class="hl-2">progress</span><span class="hl-1">: </span><span class="hl-7">number</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadStart</span><span class="hl-1">?: () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadEnd</span><span class="hl-1">?: (</span><span class="hl-2">isOk</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">): {</span><br/><span class="hl-1"> </span><span class="hl-5">execute</span><span class="hl-1">: (</span><span class="hl-2">items</span><span class="hl-1">: </span><span class="hl-7">IProcess</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1">>[]) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">loading</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">progress</span><span class="hl-1">: </span><span class="hl-7">number</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">errors</span><span class="hl-1">: { </span><span class="hl-2">label</span><span class="hl-1">: </span><span class="hl-7">string</span><span class="hl-1">; </span><span class="hl-2">message</span><span class="hl-1">: </span><span class="hl-7">string</span><span class="hl-1">; </span><span class="hl-2">error</span><span class="hl-1">: </span><span class="hl-7">Error</span><span class="hl-1"> }[];</span><br/><span class="hl-1"> </span><span class="hl-2">label</span><span class="hl-1">: </span><span class="hl-7">string</span><span class="hl-1">;</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<a id="parameters-3" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Parameters<a href="#parameters-3" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong><code>process</code></strong> <em>(required)</em> — <code>(item: { label: string; data: Data }) => Result | Promise<Result></code></p>
<p>Called once per item. Each item has a human-readable <code>label</code> (used in error reporting) and the <code>data</code> object to process.</p>
<p><strong><code>options.delay</code></strong> — <code>number</code> <em>(default: <code>0</code>)</em></p>
<p>Minimum delay in milliseconds to hold on each item before advancing. Useful for giving the UI time to render progress updates.</p>
<p><strong><code>options.onBegin</code></strong> — <code>() => void</code></p>
<p>Called once before the first item is processed.</p>
<p><strong><code>options.onEnd</code></strong> — <code>(isOk: boolean) => void</code></p>
<p>Called once after all items are processed (or after an early abort). <code>isOk</code> is <code>false</code> if any item errored.</p>
<p><strong><code>options.onFinish</code></strong> — <code>(data, errors, results) => void</code></p>
<p>Called with the full input data array, all accumulated errors, and the result array after processing finishes.</p>
<p><strong><code>options.onError</code></strong> — <code>(errors) => void | boolean</code></p>
<p>Called when an item throws. Return <code>false</code> to abort the remaining items; return <code>true</code> or <code>undefined</code> to continue processing.</p>
<p><strong><code>options.onProgress</code></strong> — <code>(progress: number) => void</code></p>
<p>Called after each item with the updated percentage (0–100).</p>
<a id="return-value-3" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Return value<a href="#return-value-3" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><table>
<thead>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>execute</code></td>
<td><code>(items: IProcess<Data>[]) => void</code></td>
<td>Starts processing the batch. Concurrent calls are blocked (single-run semantics).</td>
</tr>
<tr>
<td><code>loading</code></td>
<td><code>boolean</code></td>
<td><code>true</code> while the batch is running.</td>
</tr>
<tr>
<td><code>progress</code></td>
<td><code>number</code></td>
<td>Current percentage, 0–100.</td>
</tr>
<tr>
<td><code>errors</code></td>
<td><code>array</code></td>
<td>Items that threw, each with <code>label</code>, <code>message</code>, and <code>error</code>.</td>
</tr>
<tr>
<td><code>label</code></td>
<td><code>string</code></td>
<td>The <code>label</code> of the item currently being processed.</td>
</tr>
</tbody>
</table>
<a id="usage-3" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Usage<a href="#usage-3" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">useState</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">'react'</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">useAsyncProgress</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">'react-declarative'</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> </span><span class="hl-2">LinearProgress</span><span class="hl-1"> </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">'@mui/material/LinearProgress'</span><span class="hl-1">;</span><br/><br/><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-5">ImportContacts</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> [</span><span class="hl-10">progress</span><span class="hl-1">, </span><span class="hl-10">setProgress</span><span class="hl-1">] = </span><span class="hl-5">useState</span><span class="hl-1">(</span><span class="hl-16">0</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> { </span><span class="hl-10">execute</span><span class="hl-1">, </span><span class="hl-10">loading</span><span class="hl-1"> } = </span><span class="hl-5">useAsyncProgress</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-4">async</span><span class="hl-1"> ({ </span><span class="hl-2">data</span><span class="hl-1"> }) </span><span class="hl-4">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">api</span><span class="hl-1">.</span><span class="hl-5">createContact</span><span class="hl-1">(</span><span class="hl-2">data</span><span class="hl-1">);</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">onProgress:</span><span class="hl-1"> </span><span class="hl-2">setProgress</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">onError</span><span class="hl-2">:</span><span class="hl-1"> (</span><span class="hl-2">errors</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-5">error</span><span class="hl-1">(</span><span class="hl-3">'Some rows failed:'</span><span class="hl-1">, </span><span class="hl-2">errors</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">; </span><span class="hl-17">// continue remaining rows</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-5">onEnd</span><span class="hl-2">:</span><span class="hl-1"> (</span><span class="hl-2">isOk</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-5">navigate</span><span class="hl-1">(</span><span class="hl-2">isOk</span><span class="hl-1"> ? </span><span class="hl-3">'/success'</span><span class="hl-1"> : </span><span class="hl-3">'/report'</span><span class="hl-1">),</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> );</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">handleFileSelect</span><span class="hl-1"> = </span><span class="hl-4">async</span><span class="hl-1"> () </span><span class="hl-4">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-10">file</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-5">chooseFile</span><span class="hl-1">(</span><span class="hl-3">'.xlsx'</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">file</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-10">rows</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-5">parseExcel</span><span class="hl-1">(</span><span class="hl-2">file</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-5">execute</span><span class="hl-1">(</span><span class="hl-2">rows</span><span class="hl-1">.</span><span class="hl-5">map</span><span class="hl-1">((</span><span class="hl-2">row</span><span class="hl-1">, </span><span class="hl-2">i</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> ({ </span><span class="hl-2">label:</span><span class="hl-1"> </span><span class="hl-3">`Row </span><span class="hl-4">${</span><span class="hl-2">i</span><span class="hl-9"> </span><span class="hl-1">+</span><span class="hl-9"> </span><span class="hl-16">1</span><span class="hl-4">}</span><span class="hl-3">`</span><span class="hl-1">, </span><span class="hl-2">data:</span><span class="hl-1"> </span><span class="hl-2">row</span><span class="hl-1"> })));</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> };</span><br/><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> (</span><br/><span class="hl-1"> </span><span class="hl-6"><></span><br/><span class="hl-1"> </span><span class="hl-4">{</span><span class="hl-2">loading</span><span class="hl-9"> </span><span class="hl-1">&&</span><span class="hl-9"> </span><span class="hl-6"><</span><span class="hl-7">LinearProgress</span><span class="hl-9"> </span><span class="hl-8">variant</span><span class="hl-1">=</span><span class="hl-3">"determinate"</span><span class="hl-9"> </span><span class="hl-8">value</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">progress</span><span class="hl-4">}</span><span class="hl-9"> </span><span class="hl-6">/></span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6"><</span><span class="hl-18">button</span><span class="hl-1"> </span><span class="hl-8">onClick</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">handleFileSelect</span><span class="hl-4">}</span><span class="hl-1"> </span><span class="hl-8">disabled</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">loading</span><span class="hl-4">}</span><span class="hl-6">></span><br/><span class="hl-1"> Import XLSX</span><br/><span class="hl-1"> </span><span class="hl-6"></</span><span class="hl-18">button</span><span class="hl-6">></span><br/><span class="hl-1"> </span><span class="hl-6"></></span><br/><span class="hl-1"> );</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<hr>
<a id="useasyncvalue" class="tsd-anchor"></a><h2 class="tsd-anchor-link">useAsyncValue<a href="#useasyncvalue" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Fetches data asynchronously on mount (and whenever <code>deps</code> change) and stores the result in local state. It returns the current value, an action object for manual re-fetching, a setter for optimistic updates, and utility helpers. Think of it as <code>useState</code> combined with <code>useEffect</code> for async data.</p>
<a id="signature-4" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Signature<a href="#signature-4" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="ts"><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-5">useAsyncValue</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1">>(</span><br/><span class="hl-1"> </span><span class="hl-5">run</span><span class="hl-1">: () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">Data</span><span class="hl-1"> | </span><span class="hl-7">Promise</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1">>,</span><br/><span class="hl-1"> </span><span class="hl-2">options</span><span class="hl-1">?: {</span><br/><span class="hl-1"> </span><span class="hl-2">deps</span><span class="hl-1">?: </span><span class="hl-7">any</span><span class="hl-1">[];</span><br/><span class="hl-1"> </span><span class="hl-5">fallback</span><span class="hl-1">?: (</span><span class="hl-2">e</span><span class="hl-1">: </span><span class="hl-7">Error</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadStart</span><span class="hl-1">?: () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadEnd</span><span class="hl-1">?: (</span><span class="hl-2">isOk</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">throwError</span><span class="hl-1">?: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">): [</span><br/><span class="hl-1"> </span><span class="hl-7">Data</span><span class="hl-1"> | </span><span class="hl-7">null</span><span class="hl-1">, </span><span class="hl-17">// [0] current value</span><br/><span class="hl-1"> { </span><span class="hl-5">execute</span><span class="hl-1">: () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">Promise</span><span class="hl-1"><</span><span class="hl-7">void</span><span class="hl-1">>; </span><span class="hl-2">loading</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">; </span><span class="hl-2">error</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1"> }, </span><span class="hl-17">// [1] action controls</span><br/><span class="hl-1"> (</span><span class="hl-2">data</span><span class="hl-1">: </span><span class="hl-7">Data</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">, </span><span class="hl-17">// [2] optimistic setter</span><br/><span class="hl-1"> { </span><span class="hl-5">waitForResult</span><span class="hl-1">: () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">Promise</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1">>; </span><span class="hl-2">data$</span><span class="hl-1">: </span><span class="hl-7">MutableRefObject</span><span class="hl-1"><</span><span class="hl-7">Data</span><span class="hl-1"> | </span><span class="hl-7">null</span><span class="hl-1">> } </span><span class="hl-17">// [3] utilities</span><br/><span class="hl-1">]</span>
</code><button type="button">Copy</button></pre>
<a id="parameters-4" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Parameters<a href="#parameters-4" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong><code>run</code></strong> <em>(required)</em> — <code>() => Data | Promise<Data></code></p>
<p>Factory function called on mount and whenever <code>deps</code> change. Takes no arguments; close over variables you need.</p>
<p><strong><code>options.deps</code></strong> — <code>any[]</code> <em>(default: <code>[]</code>)</em></p>
<p>Dependency array passed to the internal <code>useEffect</code>. When any dep changes, <code>run</code> is called again.</p>
<p><strong><code>options.fallback</code></strong> — <code>(e: Error) => void</code></p>
<p>Error handler when <code>throwError</code> is <code>false</code>.</p>
<p><strong><code>options.onLoadStart</code></strong> — <code>() => void</code></p>
<p>Called before each fetch.</p>
<p><strong><code>options.onLoadEnd</code></strong> — <code>(isOk: boolean) => void</code></p>
<p>Called after each fetch.</p>
<a id="return-value-4" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Return value<a href="#return-value-4" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><table>
<thead>
<tr>
<th>Index</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>[0]</code></td>
<td><code>Data | null</code></td>
<td>The current fetched value, or <code>null</code> before the first load.</td>
</tr>
<tr>
<td><code>[1]</code></td>
<td><code>{ execute, loading, error }</code></td>
<td>Manual re-fetch control. Call <code>execute()</code> to trigger a new fetch.</td>
</tr>
<tr>
<td><code>[2]</code></td>
<td><code>(data: Data) => void</code></td>
<td>Setter for optimistic updates — replaces the stored value without a network call.</td>
</tr>
<tr>
<td><code>[3].waitForResult</code></td>
<td><code>() => Promise<Data></code></td>
<td>Resolves when a non-null value becomes available.</td>
</tr>
<tr>
<td><code>[3].data$</code></td>
<td><code>MutableRefObject<Data | null></code></td>
<td>A ref to the current value for use in callbacks without closure staleness.</td>
</tr>
</tbody>
</table>
<a id="usage-4" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Usage<a href="#usage-4" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">useAsyncValue</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">'react-declarative'</span><span class="hl-1">;</span><br/><br/><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-5">UserProfile</span><span class="hl-1">({ </span><span class="hl-2">userId</span><span class="hl-1"> }: { </span><span class="hl-2">userId</span><span class="hl-1">: </span><span class="hl-7">string</span><span class="hl-1"> }) {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> [</span><span class="hl-10">user</span><span class="hl-1">, { </span><span class="hl-10">loading</span><span class="hl-1">, </span><span class="hl-10">error</span><span class="hl-1"> }, </span><span class="hl-10">setUser</span><span class="hl-1">] = </span><span class="hl-5">useAsyncValue</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-4">async</span><span class="hl-1"> () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-2">api</span><span class="hl-1">.</span><span class="hl-5">getUser</span><span class="hl-1">(</span><span class="hl-2">userId</span><span class="hl-1">),</span><br/><span class="hl-1"> { </span><span class="hl-2">deps:</span><span class="hl-1"> [</span><span class="hl-2">userId</span><span class="hl-1">] }</span><br/><span class="hl-1"> );</span><br/><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">loading</span><span class="hl-1">) </span><span class="hl-0">return</span><span class="hl-1"> </span><span class="hl-6"><</span><span class="hl-7">Spinner</span><span class="hl-1"> </span><span class="hl-6">/></span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">error</span><span class="hl-1"> || !</span><span class="hl-2">user</span><span class="hl-1">) </span><span class="hl-0">return</span><span class="hl-1"> </span><span class="hl-6"><</span><span class="hl-7">ErrorMessage</span><span class="hl-1"> </span><span class="hl-6">/></span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">handleRename</span><span class="hl-1"> = </span><span class="hl-4">async</span><span class="hl-1"> (</span><span class="hl-2">name</span><span class="hl-1">: </span><span class="hl-7">string</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-10">updated</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">api</span><span class="hl-1">.</span><span class="hl-5">updateUser</span><span class="hl-1">(</span><span class="hl-2">userId</span><span class="hl-1">, { </span><span class="hl-2">name</span><span class="hl-1"> });</span><br/><span class="hl-1"> </span><span class="hl-5">setUser</span><span class="hl-1">(</span><span class="hl-2">updated</span><span class="hl-1">); </span><span class="hl-17">// optimistic update — no refetch</span><br/><span class="hl-1"> };</span><br/><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> </span><span class="hl-6"><</span><span class="hl-7">UserCard</span><span class="hl-1"> </span><span class="hl-8">user</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">user</span><span class="hl-4">}</span><span class="hl-1"> </span><span class="hl-8">onRename</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">handleRename</span><span class="hl-4">}</span><span class="hl-1"> </span><span class="hl-6">/></span><span class="hl-1">;</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<hr>
<a id="usepreventaction" class="tsd-anchor"></a><h2 class="tsd-anchor-link">usePreventAction<a href="#usepreventaction" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>A <strong>counting semaphore</strong> that tracks how many async operations are currently in flight. Pass <code>handleLoadStart</code> and <code>handleLoadEnd</code> as <code>onLoadStart</code>/<code>onLoadEnd</code> props to multiple buttons, and they all share a single <code>loading</code> flag. While any one is running, the <code>loading</code> boolean is <code>true</code>, so you can disable them all simultaneously.</p>
<a id="signature-5" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Signature<a href="#signature-5" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="ts"><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-5">usePreventAction</span><span class="hl-1">(</span><span class="hl-2">options</span><span class="hl-1">?: {</span><br/><span class="hl-1"> </span><span class="hl-2">disabled</span><span class="hl-1">?: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadStart</span><span class="hl-1">?: () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">onLoadEnd</span><span class="hl-1">?: (</span><span class="hl-2">isOk</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1">}): {</span><br/><span class="hl-1"> </span><span class="hl-5">handleLoadStart</span><span class="hl-1">: () </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">handleLoadEnd</span><span class="hl-1">: (</span><span class="hl-2">isOk</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">) </span><span class="hl-4">=></span><span class="hl-1"> </span><span class="hl-7">void</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">loading</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<a id="parameters-5" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Parameters<a href="#parameters-5" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong><code>options.disabled</code></strong> — <code>boolean</code></p>
<p>When <code>true</code>, forces <code>loading</code> to <code>true</code> regardless of in-flight operations. Useful for propagating an external disabled state.</p>
<p><strong><code>options.onLoadStart</code></strong> — <code>() => void</code></p>
<p>Forwarded callback called each time any tracked operation starts.</p>
<p><strong><code>options.onLoadEnd</code></strong> — <code>(isOk: boolean) => void</code></p>
<p>Forwarded callback called each time any tracked operation ends.</p>
<a id="return-value-5" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Return value<a href="#return-value-5" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><table>
<thead>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>handleLoadStart</code></td>
<td><code>() => void</code></td>
<td>Increments the internal counter. Pass as <code>onLoadStart</code> to each <code>ActionButton</code>.</td>
</tr>
<tr>
<td><code>handleLoadEnd</code></td>
<td><code>(isOk: boolean) => void</code></td>
<td>Decrements the counter. Pass as <code>onLoadEnd</code> to each <code>ActionButton</code>.</td>
</tr>
<tr>
<td><code>loading</code></td>
<td><code>boolean</code></td>
<td><code>true</code> when the counter is greater than zero, or when <code>disabled</code> is <code>true</code>.</td>
</tr>
</tbody>
</table>
<a id="usage-5" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Usage<a href="#usage-5" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">usePreventAction</span><span class="hl-1">, </span><span class="hl-2">ActionButton</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">'react-declarative'</span><span class="hl-1">;</span><br/><br/><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-5">ToolBar</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> { </span><span class="hl-10">handleLoadStart</span><span class="hl-1">, </span><span class="hl-10">handleLoadEnd</span><span class="hl-1">, </span><span class="hl-10">loading</span><span class="hl-1"> } = </span><span class="hl-5">usePreventAction</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> (</span><br/><span class="hl-1"> </span><span class="hl-6"><></span><br/><span class="hl-1"> </span><span class="hl-6"><</span><span class="hl-7">ActionButton</span><br/><span class="hl-1"> </span><span class="hl-8">disabled</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">loading</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-8">onLoadStart</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">handleLoadStart</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-8">onLoadEnd</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">handleLoadEnd</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-8">onClick</span><span class="hl-1">=</span><span class="hl-4">{async</span><span class="hl-9"> () </span><span class="hl-4">=></span><span class="hl-9"> </span><span class="hl-2">api</span><span class="hl-9">.</span><span class="hl-5">doAction1</span><span class="hl-9">()</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6">></span><br/><span class="hl-1"> Action 1</span><br/><span class="hl-1"> </span><span class="hl-6"></</span><span class="hl-7">ActionButton</span><span class="hl-6">></span><br/><br/><span class="hl-1"> </span><span class="hl-6"><</span><span class="hl-7">ActionButton</span><br/><span class="hl-1"> </span><span class="hl-8">disabled</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">loading</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-8">onLoadStart</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">handleLoadStart</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-8">onLoadEnd</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">handleLoadEnd</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-8">onClick</span><span class="hl-1">=</span><span class="hl-4">{async</span><span class="hl-9"> () </span><span class="hl-4">=></span><span class="hl-9"> </span><span class="hl-2">api</span><span class="hl-9">.</span><span class="hl-5">doAction2</span><span class="hl-9">()</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6">></span><br/><span class="hl-1"> Action 2</span><br/><span class="hl-1"> </span><span class="hl-6"></</span><span class="hl-7">ActionButton</span><span class="hl-6">></span><br/><span class="hl-1"> </span><span class="hl-6"></></span><br/><span class="hl-1"> );</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#async-hooks-usesinglerunaction-usequeuedaction-and-more"><span>Async hooks: use<wbr/>Singlerun<wbr/>Action, use<wbr/>Queued<wbr/>Action, and more</span></a><ul><li><a href="#usesinglerunaction"><span>use<wbr/>Singlerun<wbr/>Action</span></a></li><li><ul><li><a href="#signature"><span>Signature</span></a></li><li><a href="#parameters"><span>Parameters</span></a></li><li><a href="#return-value"><span>Return value</span></a></li><li><a href="#usage"><span>Usage</span></a></li></ul></li><li><a href="#usequeuedaction"><span>use<wbr/>Queued<wbr/>Action</span></a></li><li><ul><li><a href="#signature-1"><span>Signature</span></a></li><li><a href="#parameters-1"><span>Parameters</span></a></li><li><a href="#return-value-1"><span>Return value</span></a></li><li><a href="#usage-1"><span>Usage</span></a></li></ul></li><li><a href="#useasyncaction"><span>use<wbr/>Async<wbr/>Action</span></a></li><li><ul><li><a href="#signature-2"><span>Signature</span></a></li><li><a href="#parameters-2"><span>Parameters</span></a></li><li><a href="#return-value-2"><span>Return value</span></a></li><li><a href="#usage-2"><span>Usage</span></a></li></ul></li><li><a href="#useasyncprogress"><span>use<wbr/>Async<wbr/>Progress</span></a></li><li><ul><li><a href="#signature-3"><span>Signature</span></a></li><li><a href="#parameters-3"><span>Parameters</span></a></li><li><a href="#return-value-3"><span>Return value</span></a></li><li><a href="#usage-3"><span>Usage</span></a></li></ul></li><li><a href="#useasyncvalue"><span>use<wbr/>Async<wbr/>Value</span></a></li><li><ul><li><a href="#signature-4"><span>Signature</span></a></li><li><a href="#parameters-4"><span>Parameters</span></a></li><li><a href="#return-value-4"><span>Return value</span></a></li><li><a href="#usage-4"><span>Usage</span></a></li></ul></li><li><a href="#usepreventaction"><span>use<wbr/>Prevent<wbr/>Action</span></a></li><li><ul><li><a href="#signature-5"><span>Signature</span></a></li><li><a href="#parameters-5"><span>Parameters</span></a></li><li><a href="#return-value-5"><span>Return value</span></a></li><li><a href="#usage-5"><span>Usage</span></a></li></ul></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">react-declarative</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|