<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lukas Klinzing</title>
    <description>The latest articles on DEV Community by Lukas Klinzing (@theluk).</description>
    <link>https://dev.to/theluk</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F72626%2F1fdec2f8-0e32-486e-a283-6ce14fd0cf9c.jpg</url>
      <title>DEV Community: Lukas Klinzing</title>
      <link>https://dev.to/theluk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/theluk"/>
    <language>en</language>
    <item>
      <title>How to use LLM for efficient text outputs longer than 4k tokens?</title>
      <dc:creator>Lukas Klinzing</dc:creator>
      <pubDate>Mon, 10 Jun 2024 12:09:16 +0000</pubDate>
      <link>https://dev.to/theluk/how-to-use-llm-for-efficient-text-outputs-longer-than-4k-tokens-1glc</link>
      <guid>https://dev.to/theluk/how-to-use-llm-for-efficient-text-outputs-longer-than-4k-tokens-1glc</guid>
      <description>&lt;p&gt;Hey community,&lt;/p&gt;

&lt;p&gt;I wanted to share a nifty tool that could save us a lot of time and cost when we're making edits to large texts. It's called &lt;strong&gt;LLM Patcher&lt;/strong&gt;, and it's built with Next.js, the Vercel AI SDK, and OpenAI.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Time and Cost Inefficiencies
&lt;/h2&gt;

&lt;p&gt;You know how painful it can be when we ask an LLM to make changes to a large document? It always sends back the entire modified text. For big files, this means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Time Drain&lt;/strong&gt;: We end up waiting for the whole text to stream back, which is super slow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Spike&lt;/strong&gt;: It’s expensive because we’re processing and transferring more data than needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;LLM Patcher is designed to tackle these issues head-on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Ftheluk%2Fllm-patcher%2Fraw%2Fmain%2Fpublic%2Fdemo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Ftheluk%2Fllm-patcher%2Fraw%2Fmain%2Fpublic%2Fdemo.gif" alt="How LLM Patcher works Demo Video"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How LLM Patcher Works
&lt;/h2&gt;

&lt;p&gt;Here’s a quick rundown of how it streamlines the process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Input and Query&lt;/strong&gt;: You feed it the text and a find-and-replace query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text Segmentation&lt;/strong&gt;: It splits the text into lines and sentences.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identifier Prefixing&lt;/strong&gt;: Each segment gets a unique identifier (like &lt;code&gt;&amp;lt;l1s1&amp;gt;&lt;/code&gt; for line 1, sentence 1).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Find-and-Replace Execution&lt;/strong&gt;: The LLM processes each segment to apply the changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streaming Changes&lt;/strong&gt;: Instead of the whole text, it streams back just the changes in a diff format (e.g., &lt;code&gt;&amp;lt;r:l1s1&amp;gt; string to find || string to replace&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What LLM Patcher Is and Isn’t For
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What It’s Great For:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Finding and replacing text in large documents.&lt;/li&gt;
&lt;li&gt;Editing and patching texts efficiently.&lt;/li&gt;
&lt;li&gt;Specific workflows like:

&lt;ul&gt;
&lt;li&gt;Fixing typos or word replacements.&lt;/li&gt;
&lt;li&gt;Anonymizing texts by replacing names.&lt;/li&gt;
&lt;li&gt;Handling sensitive info by replacing it with placeholders.&lt;/li&gt;
&lt;li&gt;Enhancing texts with SEO keywords.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  What It’s Not Designed For:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Generating text from scratch.&lt;/li&gt;
&lt;li&gt;Summarizing or translating text.&lt;/li&gt;
&lt;li&gt;Sentiment analysis.&lt;/li&gt;
&lt;li&gt;Acting as a chatbot.&lt;/li&gt;
&lt;li&gt;General-purpose LLM tasks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Setting it up locally is straightforward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone the repo and navigate to the project directory.&lt;/li&gt;
&lt;li&gt;Set up your environment variables as defined in &lt;code&gt;.env.example&lt;/code&gt; for OpenAI integration.&lt;/li&gt;
&lt;li&gt;Install dependencies and start the dev server:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

   pnpm &lt;span class="nb"&gt;install
   &lt;/span&gt;pnpm dev


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;The app should now be live on &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;localhost:3000&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Heads Up&lt;/strong&gt;: Don’t commit your &lt;code&gt;.env&lt;/code&gt; file – it contains sensitive info.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;LLM Patcher could be a real game-changer for a lot of workflows, especially when dealing with large text edits. It’s efficient, cost-effective, and tailored for find-and-replace operations. Check out the &lt;a href="https://github.com/theluk/llm-patcher" rel="noopener noreferrer"&gt;LLM Patcher Repository&lt;/a&gt; to see it in action. You can also checkout out the live demo inside the repo!&lt;/p&gt;

&lt;p&gt;Let me know if you want to dive deeper into this or have any questions about integrating it into our current projects.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>streaming</category>
      <category>ai</category>
      <category>patch</category>
    </item>
    <item>
      <title>New Prompt &amp; Confirmation Dialog API for React</title>
      <dc:creator>Lukas Klinzing</dc:creator>
      <pubDate>Wed, 14 Jul 2021 22:44:18 +0000</pubDate>
      <link>https://dev.to/theluk/new-prompt-confirmation-dialog-api-for-react-35ae</link>
      <guid>https://dev.to/theluk/new-prompt-confirmation-dialog-api-for-react-35ae</guid>
      <description>&lt;p&gt;In React the declarative nature rules how we write our code today. With this rules in mind, showing modals, prompts or confirmation dialogs come with some additional cost of rethinking how state, effects must work. &lt;/p&gt;

&lt;h3&gt;
  
  
  Confirmation dialog in React &lt;em&gt;the old way&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Let's say we want to delete an item from a list, but before, that, we want to ask the user if he really wants to do that.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The user clicks a delete button&lt;/li&gt;
&lt;li&gt;the click handler sets a state, which indicates that a deletion action was issued and that a confirmation is requested &lt;/li&gt;
&lt;li&gt;the component needs to render a confirmation dialog&lt;/li&gt;
&lt;li&gt;the user confirms the delete action by clicking on DELETE in the confirmation dialog&lt;/li&gt;
&lt;li&gt;the dialog sets the state to "confirmed"&lt;/li&gt;
&lt;li&gt;An effect is listening to the state and if we are in a deleting state and a confirmed state, we can actually execute some remote logic.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We could model the state as following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; 
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;DELETE_REQUEST&lt;/span&gt; 
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;DELETE_CONFIRMED&lt;/span&gt; 
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;DELETE_PENDING&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;DELETED&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;our code might then look like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleDelete&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DELETE_REQUEST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleConfirm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DELETE_CONFIRMED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DELETE_CONFIRMED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DELETE_PENDING&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;deleteRemote&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// setting to null resets to initial state.&lt;/span&gt;
      &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DELETE_REQUEST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ConfirmDialog&lt;/span&gt; &lt;span class="nx"&gt;onConfirm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleConfirm&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DELETE_PENDING&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleDelete&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Delete&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now this works usually perfectly fine. We have distinct state and we can easily and safely transition from one to another.&lt;/p&gt;

&lt;p&gt;Still this is quite some boilerplate and when multiple asynchronous steps are involved, I usually do not want to put every single asynchronous step in a declarative way into states and react on them in a useEffect. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I believe an asynchronous prompt is possible in react and will solve many issues.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Prompting dynamic content
&lt;/h2&gt;

&lt;p&gt;A lot of React programmers think of JSX as a magical data structure. It is not. It is just an object holding the component function and the props. It is basically an instruction of how to render things. &lt;/p&gt;

&lt;p&gt;We can pass this jsx around the same way as anything else. &lt;/p&gt;

&lt;p&gt;One thing I do dislike about prompts in react is, that if you have let's say 10 prompts and you would like to show them all after each other, than you would need to do a lot of state management and complex rendering. &lt;/p&gt;

&lt;p&gt;because of this, I play around with this approach&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 👍 Consider this API&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setChild&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;setChild&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Why is he putting JSX into state?&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// instead of this api&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;show&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setShow&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;setShow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;show&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;as usual&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What does this do? Nothing special, just putting the instruction how to render stuff, into state. returning child will work as usual. &lt;/p&gt;

&lt;p&gt;This kind of unorthodox approach has one benefit. &lt;br&gt;
You could define what to render in a callback. &lt;/p&gt;

&lt;p&gt;So if we slightly change this, we can do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;promptContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Are you sure?&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;promptContent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when onClick is triggered, promptContent will contain the element. This is very powerful...&lt;/p&gt;

&lt;h2&gt;
  
  
  Asynchronous prompts
&lt;/h2&gt;

&lt;p&gt;Now you think, well I can maybe render from within a callback, but this does not help a lot. &lt;/p&gt;

&lt;p&gt;What if I tell you, that you can &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;be in a callback&lt;/li&gt;
&lt;li&gt;render a prompt inside of the callback&lt;/li&gt;
&lt;li&gt;waiting for the user confirmation&lt;/li&gt;
&lt;li&gt;hide the prompt while still in the callback&lt;/li&gt;
&lt;li&gt;continue the callback and do remote operations.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So I say, we can do all this, in one single callback.&lt;/p&gt;

&lt;p&gt;The key to it is that we need a hook which will additionally manage a promise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useConfirm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promiseRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setChild&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;confirm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsxElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// we return a promise and store&lt;/span&gt;
    &lt;span class="c1"&gt;// the resolve &lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nx"&gt;promiseRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleConfirm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="c1"&gt;// we hide the prompt by setting the jsx to null&lt;/span&gt;
     &lt;span class="nx"&gt;setChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="c1"&gt;// we resolve the promise&lt;/span&gt;
     &lt;span class="nx"&gt;promiseRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you could do&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;(...))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Wrapping up
&lt;/h3&gt;

&lt;p&gt;I understand that this draft and idea are in a very unpolished state. But if you want to know more, leave me a comment. &lt;/p&gt;

&lt;p&gt;Currently I am working on a library that will allow this kind of API and you will be able to bind it to the most popular UI libraries out there.&lt;/p&gt;

&lt;p&gt;You can follow me for more updates at &lt;a href="https://twitter.com/theluk246"&gt;https://twitter.com/theluk246&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>useMountedEffect: asynchronous useEffect on potentially unmounted components</title>
      <dc:creator>Lukas Klinzing</dc:creator>
      <pubDate>Sun, 11 Jul 2021 13:05:19 +0000</pubDate>
      <link>https://dev.to/theluk/usemountedeffect-asynchronous-useeffect-on-potentially-unmounted-components-5d56</link>
      <guid>https://dev.to/theluk/usemountedeffect-asynchronous-useeffect-on-potentially-unmounted-components-5d56</guid>
      <description>&lt;p&gt;When we use effects, or more precisely the &lt;code&gt;useEffect&lt;/code&gt; hook, than because very often we do want to execute something asynchronously. In most scenarios we are doing this when a component gets mounted. &lt;/p&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Component gets mounted&lt;/li&gt;
&lt;li&gt;useEffect gets executed&lt;/li&gt;
&lt;li&gt;we set the state that we are starting to load something&lt;/li&gt;
&lt;li&gt;we fetch data from the server&lt;/li&gt;
&lt;li&gt;ups... the user navigated away&lt;/li&gt;
&lt;li&gt;our component gets unmounted&lt;/li&gt;
&lt;li&gt;our async function resolves finally&lt;/li&gt;
&lt;li&gt;happy that we got data from server, we call setState to update our component&lt;/li&gt;
&lt;li&gt;error: component shouts at us because we set state on something that does not exist anymore&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;So what is the solution here? Well, React tells us already, when it unmounted the component. We just need to listen to what React tells us, but unfortunately it is not that straight forward and looks also a little bit weird. &lt;/p&gt;

&lt;p&gt;But because every hook can ask for a callback for the event of unmounting, we can abstract the handling of state whether we are mounted or not into a custom hook. &lt;/p&gt;

&lt;h3&gt;
  
  
  useMountedEffect
&lt;/h3&gt;

&lt;p&gt;this hook basically is the same as the &lt;code&gt;useEffect&lt;/code&gt; but has a 3 different points. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;it can be asynchronous&lt;/li&gt;
&lt;li&gt;the callback passed in will receive a &lt;code&gt;isMounted&lt;/code&gt; function&lt;/li&gt;
&lt;li&gt;you cannot return a unmount funciton by yourself unfortunately&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Here is how it looks
&lt;/h4&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  So What happens here?
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;We define the arguments of the hook.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is very similar to the original &lt;code&gt;useEffect&lt;/code&gt;. It has the dependency array, but the callback you pass in, will receive a &lt;code&gt;isMounted&lt;/code&gt; function. You can call this function whenever you want to check if the component is mounted or not. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We create two &lt;code&gt;Ref&lt;/code&gt;s using &lt;code&gt;useRef&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I use ref's for everything that does not require reactivity and if I am only interested in the latest version of some value. &lt;/p&gt;

&lt;p&gt;Here we do not want to "react" if your callback changes, or if we get unmounted/mounted. We want to &lt;strong&gt;only&lt;/strong&gt; react to changes, if the dependency array changes. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The hook stores the current state whether it is mounted or not. To get this state, we define a function that resolves with the mounted reference. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The hook calls the current callback. The callback can change but we call it only if the dependency array changes, so it works basically exactly like useEffect. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the callback now should check whether it should set a state based on the information &lt;code&gt;isMounted()&lt;/code&gt; returns. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setStatus&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;useMountedEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isMounted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LOADIGN&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetchMyData&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="c1"&gt;// only set state if we are still mounted&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isMounted&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;setStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DONE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isMounted&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;setStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ERROR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>react</category>
      <category>typescript</category>
      <category>reacthooks</category>
    </item>
    <item>
      <title>useLocal: the useState hook for a properly-synced state</title>
      <dc:creator>Lukas Klinzing</dc:creator>
      <pubDate>Sun, 11 Jul 2021 12:28:56 +0000</pubDate>
      <link>https://dev.to/theluk/uselocal-the-usestate-hook-for-a-properly-synced-state-32kp</link>
      <guid>https://dev.to/theluk/uselocal-the-usestate-hook-for-a-properly-synced-state-32kp</guid>
      <description>&lt;p&gt;As you might know, the React hook &lt;code&gt;useState&lt;/code&gt; takes one argument, which will initialize its internal state to that given value. When React 16 with Hooks got released, I found it a little bit confusing, but it perfectly makes sense.&lt;/p&gt;

&lt;p&gt;No matter what, there are still situations, where you need to update the state based on the incoming props. Usually that is done using a &lt;code&gt;useEffect&lt;/code&gt; hook, where you listen on the incoming prop to change, and then update your local state. &lt;/p&gt;

&lt;p&gt;This is a great way of handling it, because you, as the owner of the component can perfectly control, if the parent prop change is actually what you want. It could even break your component if the parent decides to update a prop during a critical state of your component. &lt;/p&gt;

&lt;p&gt;But there are also situations, where not much can happen. There are simple scenarios where you basically want to hold a local version and not propagate it up the tree until a certain condition happen. During that time, you still want to allow the parent controlling component to update the local value, if that is what it wants. &lt;/p&gt;

&lt;p&gt;Here is an example how to allow the parent controlling component set (and update, if necessary) the from and to values. It can happen that for example for whatever reason, there is another component, that can set a date range, for that, we would want that from and to can be updated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RangeDatepicker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFrom&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLocal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLocal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyCalendarRangePicker&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onChangeFrom&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setFrom&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onChangeTo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setTo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;the easiest implementation of such a hook (in Typscript) looks like this&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;One further improvement would be, to pass in some conditional function that checks, if it is allowed to update the local state. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;You can visit the gist here&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/theluk/13b7a17455b599699b7d34775cbf8273"&gt;https://gist.github.com/theluk/13b7a17455b599699b7d34775cbf8273&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>hooks</category>
      <category>usestate</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
