<?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: aldrin</title>
    <description>The latest articles on DEV Community by aldrin (@aldrin).</description>
    <link>https://dev.to/aldrin</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%2F146987%2F16782fa8-92f3-4b51-a4ce-b05cfc311aea.png</url>
      <title>DEV Community: aldrin</title>
      <link>https://dev.to/aldrin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aldrin"/>
    <language>en</language>
    <item>
      <title>React 18 things : useDeferredValue</title>
      <dc:creator>aldrin</dc:creator>
      <pubDate>Tue, 26 Apr 2022 17:53:39 +0000</pubDate>
      <link>https://dev.to/aldrin/react-18-things-usedeferredvalue-35oj</link>
      <guid>https://dev.to/aldrin/react-18-things-usedeferredvalue-35oj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;References: &lt;br&gt;
&lt;a href="https://reactjs.org/docs/hooks-reference.html#usedeferredvalue" rel="noopener noreferrer"&gt;React docs: useDeferredValue&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/reactwg/react-18/discussions/129" rel="noopener noreferrer"&gt;Discussions: useDeferredValue&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;useDeferredValue&lt;/code&gt; is a new hook in react which can be used to defer non-urgent updates triggered by some action like a state update.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useDeferredValue&lt;/code&gt; hook accepts a value and returns a new copy of the value that will defer to more urgent updates. If react is busy, like rendering an urgent update, the return value will be the previous value and once the urgent update is completed, you will get the updated value from the hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState, useEffect, useDeferredValue } from "react";

function App({data}) {
    const [query, setQuery] = useState("");
    const [result, setResult] = useState(data);

    // Showing result is non-urgent update
    const deferredQuery = useDeferredValue(query);

  useEffect(() =&amp;gt; {
      const searchResult = search(data, deferredQuery);
      setResult(searchResult);
  }, [deferredQuery]);

  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;label htmlFor="search users"&amp;gt;Search: &amp;lt;/label&amp;gt;
      &amp;lt;input
        type="search"
        value={query}
        onChange={(e) =&amp;gt; setQuery(e.target.value)} // urgent update
      /&amp;gt;

        &amp;lt;DataView data={result}/&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;Here search will be performed on the deferred query and show the search result is a non-urgent update. But showing what the user typed in the input field is an urgent update. Let's go in deep,&lt;/p&gt;

&lt;p&gt;Let's say you entered the search query "toy",&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In React 17 or before,&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;On "t", update the state of the input to "t", perform a search for "t" and update the state to show results.&lt;/li&gt;
&lt;li&gt;On "o", update the state of the input to "to", perform a search for "to" and update the state to show results.&lt;/li&gt;
&lt;li&gt;On "y", update the state of the input to "toy", perform a search for "toy" and update the state to show results.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;In React 18: using useDeferredValue,&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;On "t", update the state of the input to "t" and since there is an urgent update pending (user typed "o", need to update input state), useDeferredValue hook return old value "", so no search performed.&lt;/li&gt;
&lt;li&gt;On "o", update the state of the input to "to" and since there is an urgent update pending (user typed "y", need to update input state), useDeferredValue hook return old value "", so no search performed.&lt;/li&gt;
&lt;li&gt;On "y", update the state of the input to "toy" and since there is no urgent update pending useDeferredValue hook returns new value "toy" and the search will be performed and ui will show search results.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This hook is similar to a debouncing hook like &lt;a href="https://react-use-custom-hooks.vercel.app/docs/useDebounce" rel="noopener noreferrer"&gt;useDebounce&lt;/a&gt; but the benefit of using &lt;code&gt;useDeferredValue&lt;/code&gt; is that React will work on the update as soon as other work finishes (instead of waiting for an arbitrary amount of time). &lt;/p&gt;

&lt;p&gt;So if you use the &lt;code&gt;useDeferredValue&lt;/code&gt; hook, in high-end machines the non-urgent updates will be faster than in low-end machines since high-end machines can process updates quickly. But in the case of &lt;code&gt;useDebounce&lt;/code&gt;, the delay for a non-urgent update will be the same in both cases and hence we won't be able to leverage the full resources available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;We can create a better user experience if have an option to tell react which update is urgent and which is non-urgent since we will have more control over the UI updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html" rel="noopener noreferrer"&gt;Upgrade to react 18&lt;/a&gt;, and use the &lt;code&gt;useDeferredValue&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
With &lt;code&gt;useDeferredValue&lt;/code&gt;: &lt;a href="https://codesandbox.io/s/react-18-usedeferredvalue-s4lgn2" rel="noopener noreferrer"&gt;https://codesandbox.io/s/react-18-usedeferredvalue-s4lgn2&lt;/a&gt;&lt;br&gt;
Without &lt;code&gt;useDeferredValue&lt;/code&gt;:  &lt;a href="https://codesandbox.io/s/react-18-no-usedeferredvalue-wvel7c" rel="noopener noreferrer"&gt;https://codesandbox.io/s/react-18-no-usedeferredvalue-wvel7c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try enabling CPU throttling to see the difference&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0miux3m0smtpw5mgzkt5.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0miux3m0smtpw5mgzkt5.png" alt="CPU throttling in browser-useDeferredValue-react18"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>React 18 things : Automatic Batching</title>
      <dc:creator>aldrin</dc:creator>
      <pubDate>Mon, 11 Apr 2022 17:38:37 +0000</pubDate>
      <link>https://dev.to/aldrin/react-18-things-automatic-batching-1of4</link>
      <guid>https://dev.to/aldrin/react-18-things-automatic-batching-1of4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;References: &lt;br&gt;
&lt;a href="https://reactjs.org/blog/2022/03/29/react-v18.html#new-feature-automatic-batching"&gt;New Feature: Automatic Batching&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/reactwg/react-18/discussions/21"&gt;Discussions: Automatic Batching&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What?
&lt;/h2&gt;

&lt;p&gt;Batching in react is the process of grouping multiple state updates into a single re-render. Automatic batching is present in react inside React event handlers, for example, inside handler for a click event. But it was not present for updates inside promises, setTimeout, native event handlers etc. in React 17 or earlier versions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  useEffect(() =&amp;gt; {
    fetchData().then(() =&amp;gt; {
      // React 17 or earlier does NOT batch these updates 
      // These will be two different updates
      setData(data); // 1st update and re-render
      setLoading(false); // 2nd update and re-render
    });
  }, []);

  return (...)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With React 18, all updates will be automatically batched, no matter where they originate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  useEffect(() =&amp;gt; {
    fetchData().then(() =&amp;gt; {
      // React 18 and later batch these updates
      setData(data); 
      setLoading(false); 
     // Re-render only once at the end 🥳
    });
  }, []);

  return (...)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;Performance reasons: When multiple state updates batch into a single render, we could avoid unnecessary re-renders and thus improve the performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html"&gt;Upgrade to react 18&lt;/a&gt;, this functionality is only available in react 18. It is expected to &lt;a href="https://github.com/reactwg/react-18/discussions/5"&gt;replace render with createRoot&lt;/a&gt; as part of adopting React 18.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to opt out?
&lt;/h2&gt;

&lt;p&gt;That is a rare case 🤔, you can use &lt;code&gt;ReactDOM.flushSync()&lt;/code&gt; to opt out of automatic batching.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { flushSync } from 'react-dom';

function App() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  useEffect(() =&amp;gt; {
    fetchData().then(() =&amp;gt; {
      flushSync(() =&amp;gt; {
        setData(data); // 1st update and re-render
      });
      flushSync(() =&amp;gt; {
        setLoading(false); // 2nd update and re-render
      });

    });
  }, []);

  return ()
}

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

&lt;/div&gt;



</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
