<?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: Abreham</title>
    <description>The latest articles on DEV Community by Abreham (@abrehamgezahegn).</description>
    <link>https://dev.to/abrehamgezahegn</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%2F331862%2F246627b7-18f3-4cb2-9379-d80296d3485e.jpeg</url>
      <title>DEV Community: Abreham</title>
      <link>https://dev.to/abrehamgezahegn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abrehamgezahegn"/>
    <language>en</language>
    <item>
      <title>Optimizing a long list for re-renders using useReducer ,memo and useCallback. 
</title>
      <dc:creator>Abreham</dc:creator>
      <pubDate>Fri, 02 Apr 2021 21:05:15 +0000</pubDate>
      <link>https://dev.to/abrehamgezahegn/optimizing-a-long-list-for-re-renders-using-usereducer-memo-and-usecallback-4c65</link>
      <guid>https://dev.to/abrehamgezahegn/optimizing-a-long-list-for-re-renders-using-usereducer-memo-and-usecallback-4c65</guid>
      <description>&lt;p&gt;Long lists in react that can't be paginated can cause expensive re-renders reacting to a small change, rendering the whole application obsolete, get it :)? &lt;/p&gt;

&lt;p&gt;In this post, we will explore that problem using a simple todo app with a very long list of todos for demonstration purposes. The knowledge can be applied to any similar situation not limited to todo apps.&lt;br&gt;
 &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgl37lxbyz3i2ajvyec1q.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%2Fgl37lxbyz3i2ajvyec1q.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
 &lt;br&gt;
 &lt;/p&gt;
&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt; &lt;br&gt;
Let’s assume a to-do list with 1000 items. And each item has a completed status and toggle. &lt;br&gt;
N - not complete and &lt;br&gt;
C - completed&lt;/p&gt;

&lt;p&gt;Now let’s toggle item 3's completed status,&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejvdfcbgby83bi4ax79j.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%2Fejvdfcbgby83bi4ax79j.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
The whole todo item component is re-rendered even though only item 3 is changed. This will cause a major lag. The effect is noticeable even for simple text-based list. &lt;/p&gt;

&lt;p&gt; &lt;br&gt;
 &lt;/p&gt;
&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt; &lt;br&gt;
Let's introduce reducer to handle the state,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [state, dispatch] = useReducer(todoReducer, initialState);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;dispatch&lt;/code&gt; doesn’t change between state changes. So we can leverage that to avoid re-renders. We basically declare our context state as above. &lt;/p&gt;

&lt;p&gt;Our toggle function in context. Here we will have to wrap the function with useCallback and provide only dispatch as a dependency. By doing this we make sure the function isn’t re-created every time the state is changed. And it will help when passing the function as a prop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const toggleCompleted = useCallback(
   (id: number) =&amp;gt; {
     dispatch({ type: "MARK_AS_COMPLETED", payload: id });
   }, 
   [dispatch]
 );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only catch here is that we cannot access the latest state in this function. Because it’s never updated with the state.&lt;/p&gt;

&lt;p&gt;To overcome that we will have to access our state in the reducer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;else if (action.type === "MARK_AS_COMPLETED") {
   // here we can get the latest state
   const updated = state.todoList.map((item) =&amp;gt; {
     if (item.id === action.payload) {
       return { ...item, completed: !item.completed };
     }
     return item;
   });
   return {
     ...state, 
     todoList: updated,
   };
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the todo item will be wrapped with memo. By doing this we make sure that todo and &lt;code&gt;toggleCompleted&lt;/code&gt; stay the same between re-renders. And memo will be able to avoid the re-rendering of the component. &lt;br&gt;
And when using memo we cannot access a context inside that component. We will have to pass the values as a prop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default memo(TodoItem);

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

&lt;/div&gt;



&lt;p&gt;That’s it. TodoItem is memorized. &lt;br&gt;
 &lt;br&gt;
 &lt;br&gt;
Now let's try toggling item 3.&lt;br&gt;
 &lt;/p&gt;

&lt;h3&gt;
  
  
  The result
&lt;/h3&gt;

&lt;p&gt; &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%2Frnh47cxccrju8ccnwfi6.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%2Frnh47cxccrju8ccnwfi6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Only item 3 is re-rendered. &lt;br&gt;
 &lt;br&gt;
 &lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
mic drop&lt;/p&gt;

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