react-declarative-docs / documents /docs_api_hooks_async-hooks.html
tripolskypetr's picture
patch
9375fc1
<!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">&lt;</span><span class="hl-7">Data</span><span class="hl-1">, </span><span class="hl-7">Payload</span><span class="hl-1">&gt;(</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">=&gt;</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">&lt;</span><span class="hl-7">Data</span><span class="hl-1">&gt;,</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</span><span class="hl-1"> </span><span class="hl-7">Promise</span><span class="hl-1">&lt;</span><span class="hl-7">Data</span><span class="hl-1"> | </span><span class="hl-7">null</span><span class="hl-1">&gt;;</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) =&gt; Data | Promise&lt;Data&gt;</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>() =&gt; 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) =&gt; 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) =&gt; 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?) =&gt; Promise&lt;Data | null&gt;</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">&#39;react-declarative&#39;</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">=&gt;</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">=&gt;</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">&#39;image/jpeg,image/png&#39;</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">&lt;</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">&gt;</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">&#39;Uploading…&#39;</span><span class="hl-9"> </span><span class="hl-1">:</span><span class="hl-9"> </span><span class="hl-3">&#39;Upload image&#39;</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;/</span><span class="hl-18">button</span><span class="hl-6">&gt;</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">&lt;</span><span class="hl-7">Data</span><span class="hl-1">, </span><span class="hl-7">Payload</span><span class="hl-1">&gt;(</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">=&gt;</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">&lt;</span><span class="hl-7">Data</span><span class="hl-1">&gt;,</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</span><span class="hl-1"> </span><span class="hl-7">Promise</span><span class="hl-1">&lt;</span><span class="hl-7">Data</span><span class="hl-1"> | </span><span class="hl-7">null</span><span class="hl-1">&gt;;</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) =&gt; Data | Promise&lt;Data&gt;</code></p>
<p>The async function to execute for each queued item.</p>
<p><strong><code>options.onLoadStart</code></strong><code>() =&gt; void</code></p>
<p>Called before each queued execution begins.</p>
<p><strong><code>options.onLoadEnd</code></strong><code>(isOk: boolean) =&gt; void</code></p>
<p>Called after each queued execution completes or fails.</p>
<p><strong><code>options.fallback</code></strong><code>(e: Error) =&gt; 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?) =&gt; Promise&lt;Data | null&gt;</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">&#39;react&#39;</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">&#39;react-declarative&#39;</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">=&gt;</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">&#39;create&#39;</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">&#39;update&#39;</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">&#39;remove&#39;</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</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">&lt;</span><span class="hl-7">Board</span><span class="hl-1"> </span><span class="hl-6">/&gt;</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">&lt;</span><span class="hl-7">Data</span><span class="hl-1">, </span><span class="hl-7">Payload</span><span class="hl-1">&gt;(</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">=&gt;</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">&lt;</span><span class="hl-7">Data</span><span class="hl-1">&gt;,</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</span><span class="hl-1"> </span><span class="hl-7">Promise</span><span class="hl-1">&lt;</span><span class="hl-7">Data</span><span class="hl-1"> | </span><span class="hl-7">null</span><span class="hl-1">&gt;;</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) =&gt; Data | Promise&lt;Data&gt;</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>() =&gt; void</code></p>
<p>Called before each execution.</p>
<p><strong><code>options.onLoadEnd</code></strong><code>(isOk: boolean) =&gt; void</code></p>
<p>Called after each execution.</p>
<p><strong><code>options.fallback</code></strong><code>(e: Error) =&gt; 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?) =&gt; Promise&lt;Data | null&gt;</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">&#39;react-declarative&#39;</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">=&gt;</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">=&gt;</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">&lt;&gt;</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">&amp;&amp;</span><span class="hl-9"> </span><span class="hl-6">&lt;</span><span class="hl-18">span</span><span class="hl-6">&gt;</span><span class="hl-9">Save failed — please try again.</span><span class="hl-6">&lt;/</span><span class="hl-18">span</span><span class="hl-6">&gt;</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;</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">=&gt;</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">&gt;</span><br/><span class="hl-1"> Save</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;/</span><span class="hl-18">button</span><span class="hl-6">&gt;</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;/&gt;</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>&lt;LinearProgress /&gt;</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">&lt;</span><span class="hl-7">Data</span><span class="hl-1">&gt; {</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">&lt;</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">&gt;(</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">&lt;</span><span class="hl-7">Data</span><span class="hl-1">&gt;) </span><span class="hl-4">=&gt;</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">&lt;</span><span class="hl-7">Result</span><span class="hl-1">&gt;,</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</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">&lt;</span><span class="hl-7">Data</span><span class="hl-1">&gt;[]) </span><span class="hl-4">=&gt;</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 }) =&gt; Result | Promise&lt;Result&gt;</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>() =&gt; void</code></p>
<p>Called once before the first item is processed.</p>
<p><strong><code>options.onEnd</code></strong><code>(isOk: boolean) =&gt; 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) =&gt; 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) =&gt; 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) =&gt; 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&lt;Data&gt;[]) =&gt; 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">&#39;react&#39;</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">&#39;react-declarative&#39;</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">&#39;@mui/material/LinearProgress&#39;</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">=&gt;</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">=&gt;</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">&#39;Some rows failed:&#39;</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">=&gt;</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">&#39;/success&#39;</span><span class="hl-1"> : </span><span class="hl-3">&#39;/report&#39;</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">=&gt;</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">&#39;.xlsx&#39;</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">=&gt;</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">&lt;&gt;</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">&amp;&amp;</span><span class="hl-9"> </span><span class="hl-6">&lt;</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">&quot;determinate&quot;</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">/&gt;</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;</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">&gt;</span><br/><span class="hl-1"> Import XLSX</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;/</span><span class="hl-18">button</span><span class="hl-6">&gt;</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;/&gt;</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">&lt;</span><span class="hl-7">Data</span><span class="hl-1">&gt;(</span><br/><span class="hl-1"> </span><span class="hl-5">run</span><span class="hl-1">: () </span><span class="hl-4">=&gt;</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">&lt;</span><span class="hl-7">Data</span><span class="hl-1">&gt;,</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</span><span class="hl-1"> </span><span class="hl-7">Promise</span><span class="hl-1">&lt;</span><span class="hl-7">void</span><span class="hl-1">&gt;; </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">=&gt;</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">=&gt;</span><span class="hl-1"> </span><span class="hl-7">Promise</span><span class="hl-1">&lt;</span><span class="hl-7">Data</span><span class="hl-1">&gt;; </span><span class="hl-2">data$</span><span class="hl-1">: </span><span class="hl-7">MutableRefObject</span><span class="hl-1">&lt;</span><span class="hl-7">Data</span><span class="hl-1"> | </span><span class="hl-7">null</span><span class="hl-1">&gt; } </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>() =&gt; Data | Promise&lt;Data&gt;</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) =&gt; void</code></p>
<p>Error handler when <code>throwError</code> is <code>false</code>.</p>
<p><strong><code>options.onLoadStart</code></strong><code>() =&gt; void</code></p>
<p>Called before each fetch.</p>
<p><strong><code>options.onLoadEnd</code></strong><code>(isOk: boolean) =&gt; 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) =&gt; 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>() =&gt; Promise&lt;Data&gt;</code></td>
<td>Resolves when a non-null value becomes available.</td>
</tr>
<tr>
<td><code>[3].data$</code></td>
<td><code>MutableRefObject&lt;Data | null&gt;</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">&#39;react-declarative&#39;</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">=&gt;</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">&lt;</span><span class="hl-7">Spinner</span><span class="hl-1"> </span><span class="hl-6">/&gt;</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">&lt;</span><span class="hl-7">ErrorMessage</span><span class="hl-1"> </span><span class="hl-6">/&gt;</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">=&gt;</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">&lt;</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">/&gt;</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</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>() =&gt; void</code></p>
<p>Forwarded callback called each time any tracked operation starts.</p>
<p><strong><code>options.onLoadEnd</code></strong><code>(isOk: boolean) =&gt; 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>() =&gt; 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) =&gt; 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">&#39;react-declarative&#39;</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">&lt;&gt;</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;</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">=&gt;</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">&gt;</span><br/><span class="hl-1"> Action 1</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;/</span><span class="hl-7">ActionButton</span><span class="hl-6">&gt;</span><br/><br/><span class="hl-1"> </span><span class="hl-6">&lt;</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">=&gt;</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">&gt;</span><br/><span class="hl-1"> Action 2</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;/</span><span class="hl-7">ActionButton</span><span class="hl-6">&gt;</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;/&gt;</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>