<?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: Ola Abaza</title>
    <description>The latest articles on DEV Community by Ola Abaza (@ola_1313).</description>
    <link>https://dev.to/ola_1313</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%2F1903700%2F206631c9-2c10-469a-9a21-32adf37b2e14.png</url>
      <title>DEV Community: Ola Abaza</title>
      <link>https://dev.to/ola_1313</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ola_1313"/>
    <language>en</language>
    <item>
      <title>1 RN Thing a Day – Day 15: What is createListenerMiddleware</title>
      <dc:creator>Ola Abaza</dc:creator>
      <pubDate>Sun, 07 Jun 2026 10:08:17 +0000</pubDate>
      <link>https://dev.to/ola_1313/1-rn-thing-a-day-day-15-what-is-createlistenermiddleware-5mb</link>
      <guid>https://dev.to/ola_1313/1-rn-thing-a-day-day-15-what-is-createlistenermiddleware-5mb</guid>
      <description>&lt;p&gt;&lt;strong&gt;createListenerMiddleware&lt;/strong&gt; is a feature from Redux Toolkit that allows you to listen for actions or state changes and run side effects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why was it created?&lt;/strong&gt;&lt;br&gt;
Before createListenerMiddleware, developers typically used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;useEffect&lt;/li&gt;
&lt;li&gt;Custom middleware&lt;/li&gt;
&lt;li&gt;Redux Thunk&lt;/li&gt;
&lt;li&gt;Redux Saga&lt;/li&gt;
&lt;li&gt;Redux Observable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;for side effects.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Redux Toolkit introduced createListenerMiddleware as a simpler alternative for many common use cases.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;There are two Ways to Listen:-&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;By Action
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;startListening&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;actionCreator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="na"&gt;effect&lt;/span&gt;&lt;span class="p"&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Item added&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Runs only when:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="c1"&gt;//is dispatched.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.By Predicate&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;startListening&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;predicate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;previousState&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;currentState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;previousState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="na"&gt;effect&lt;/span&gt;&lt;span class="p"&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cart grew&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Runs whenever the cart gets bigger, regardless of which action caused it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does startListening() do?&lt;/strong&gt;&lt;br&gt;
It registers a listener.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;listenerMiddleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startListening&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;actionCreator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;someAction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="na"&gt;effect&lt;/span&gt;&lt;span class="p"&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;// side effect&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;Similar to:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Listen for someAction&lt;br&gt;
      ↓&lt;br&gt;
When it happens&lt;br&gt;
      ↓&lt;br&gt;
Run effect&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What can you do inside the effect?&lt;/strong&gt;&lt;br&gt;
You get access to a listenerApi.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;effect&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;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;listenerApi&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;listenerApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetchUser&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;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;listenerApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getState&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;listenerApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&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="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// we can also Cancel Running Effects &lt;/span&gt;

&lt;span class="c1"&gt;//listenerApi.cancelActiveListeners()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Where is it added?&lt;/strong&gt;&lt;br&gt;
In your store configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;listenerMiddleware&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nf"&gt;createListenerMiddleware&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;configureStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="na"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;getDefaultMiddleware&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nf"&gt;getDefaultMiddleware&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;prepend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;listenerMiddleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;middleware&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;&lt;strong&gt;Simple Definition&lt;/strong&gt;&lt;br&gt;
createListenerMiddleware is a Redux Toolkit middleware that lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Listen for specific actions (actionCreator)&lt;/li&gt;
&lt;li&gt;Listen for specific state transitions (predicate)&lt;/li&gt;
&lt;li&gt;Execute side effects (effect)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;without putting that logic inside React components. It helps keep application behavior separate from UI behavior.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Let's understand what happens when you dispatch an action in Redux.&lt;/strong&gt;&lt;br&gt;
Without Middleware&lt;/p&gt;

&lt;p&gt;When you do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Redux follows this flow:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dispatch(action)&lt;br&gt;
       ↓&lt;br&gt;
reducer&lt;br&gt;
       ↓&lt;br&gt;
new state&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Middleware?&lt;/strong&gt;&lt;br&gt;
Middleware is code that sits between:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dispatch()&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
and&lt;/p&gt;

&lt;p&gt;&lt;code&gt;reducer()&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Think of it as a security checkpoint at an airport.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;In Redux:&lt;br&gt;
Action&lt;br&gt;
    ↓&lt;br&gt;
Middleware&lt;br&gt;
    ↓&lt;br&gt;
Reducer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Every dispatched action passes through middleware first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Does the Predicate Have Access to Both States?&lt;/strong&gt;&lt;br&gt;
Because listener middleware watches the entire process.&lt;/p&gt;

&lt;p&gt;Imagine it takes a snapshot:&lt;br&gt;
&lt;/p&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;previousState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;before the reducer runs.&lt;/p&gt;

&lt;p&gt;Then after the reducer:&lt;br&gt;
&lt;/p&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;currentState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Now it can compare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;predicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;previousState&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//Example:&lt;/span&gt;

&lt;span class="nx"&gt;predicate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&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;previous&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoggedIn&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoggedIn&lt;/span&gt;

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;we mean it participates in the dispatch pipeline and has visibility into the action and the state transition, allowing it to react after the state changes. That's what makes Predicate &amp;amp; Effect possible.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>100daysofreactnative</category>
      <category>redux</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>1 RN Thing a Day – Day 14: Predicate &amp; Effect Patterns in React Native</title>
      <dc:creator>Ola Abaza</dc:creator>
      <pubDate>Sun, 24 May 2026 10:40:01 +0000</pubDate>
      <link>https://dev.to/ola_1313/1-rn-thing-a-day-day-14-predicate-effect-patterns-in-react-native-3joo</link>
      <guid>https://dev.to/ola_1313/1-rn-thing-a-day-day-14-predicate-effect-patterns-in-react-native-3joo</guid>
      <description>&lt;p&gt;The easiest way to think about it is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Predicate&lt;/strong&gt; = Watch for something&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Effect&lt;/strong&gt; = Do something when it happens&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;predicate: Is someone entering the building?
effect: Check their ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example 1: Add Item To Cart&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="c1"&gt;// cartSlice.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createSlice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PayloadAction&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@reduxjs/toolkit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CartState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Product&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;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CartState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;items&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;cartSlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSlice&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;reducers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;addItem&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="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PayloadAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;&amp;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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;removeItem&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="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PayloadAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&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;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&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="k"&gt;export&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;addItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;removeItem&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cartSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;cartSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;

&lt;span class="c1"&gt;// listenerMiddleware.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createListenerMiddleware&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@reduxjs/toolkit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Toast&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native-toast-message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;listenerMiddleware&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nf"&gt;createListenerMiddleware&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// cartListeners.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;listenerMiddleware&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./listenerMiddleware&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;listenerMiddleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startListening&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;predicate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;previousState&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;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;previousState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;effect&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;text1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Item added to cart&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why use a predicate instead of listening to addItem directly?&lt;/strong&gt;&lt;br&gt;
You could do:&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="nx"&gt;listenerMiddleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startListening&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;actionCreator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;effect&lt;/span&gt;&lt;span class="p"&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;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;text1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Item added to cart&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the predicate version is more powerful because it reacts to state changes, not specific actions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The predicate doesn't know or care which action happened. It only cares about the resulting state.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, if items are added by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;syncCartFromServer&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;restoreSavedCart&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the same predicate still works:&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="nx"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;previousState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because it only cares that the cart grew, regardless of which action caused it. That's the main strength of the Predicate &amp;amp; Effect pattern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Compare Current State and Previous State?&lt;/strong&gt;&lt;br&gt;
Because many actions happen in the app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For example: User adds item to cart

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

&lt;/div&gt;



&lt;p&gt;Without comparing states, your effect might run every time.&lt;/p&gt;

&lt;p&gt;Instead, the predicate asks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the specific thing I care about change?

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

&lt;/div&gt;



&lt;p&gt;Only then does it execute the effect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When should I use actionCreator?&lt;/strong&gt;&lt;br&gt;
Use it when your business rule is: "When this action happens, do something."&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;Track&lt;/span&gt; &lt;span class="nx"&gt;Login&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt;
&lt;span class="nf"&gt;startListening&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;actionCreator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;loginSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;effect&lt;/span&gt;&lt;span class="p"&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;Analytics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;track&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Login&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You specifically want to react to the login action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When should I use predicate?&lt;/strong&gt;&lt;br&gt;
Use it when your business rule is:"When the state becomes this, do something."&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="nx"&gt;Became&lt;/span&gt; &lt;span class="nx"&gt;Logged&lt;/span&gt; &lt;span class="nx"&gt;In&lt;/span&gt;
&lt;span class="nx"&gt;predicate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&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;previous&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoggedIn&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoggedIn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maybe several actions can lead to a logged-in state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;loginSuccess&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;restoreSession&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;refreshTokenSuccess&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't want to listen to all of them.&lt;/p&gt;

&lt;p&gt;You just care that: isLoggedIn changed from false to true&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why not just use useEffect?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For small apps, useEffect is often enough. Predicate &amp;amp; Effect becomes valuable when you want to move business logic outside the UI layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem With useEffect&lt;/strong&gt;&lt;br&gt;
Imagine this: When a user logs in, you need to:&lt;/p&gt;

&lt;p&gt;Fetch profile&lt;br&gt;
Load permissions&lt;br&gt;
Connect websocket&lt;br&gt;
Start analytics session&lt;/p&gt;

&lt;p&gt;Many developers write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;HomeScreen&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;isLoggedIn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectIsLoggedIn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nf"&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;isLoggedIn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetchProfile&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;loadPermissions&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="nf"&gt;connectWebSocket&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="nf"&gt;startAnalytics&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;isLoggedIn&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 ask yourself:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is HomeScreen responsible for login behavior?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It isn't really a UI concern.&lt;/p&gt;

&lt;p&gt;It's application behavior.&lt;/p&gt;

&lt;p&gt;The app should perform these actions whenever a user becomes logged in, regardless of which screen is mounted.&lt;/p&gt;

&lt;p&gt;This is where Predicate &amp;amp; Effect shines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple Rule&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use useEffect when:&lt;/p&gt;

&lt;p&gt;The effect belongs to the component.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focus input&lt;/li&gt;
&lt;li&gt;Start animation&lt;/li&gt;
&lt;li&gt;Listen to keyboard&lt;/li&gt;
&lt;li&gt;Set navigation title&lt;/li&gt;
&lt;li&gt;Fetch data only for this screen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use Predicate &amp;amp; Effect when:&lt;/strong&gt;&lt;br&gt;
The effect belongs to the application.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User logged in&lt;/li&gt;
&lt;li&gt;User logged out&lt;/li&gt;
&lt;li&gt;Network restored&lt;/li&gt;
&lt;li&gt;Language changed&lt;/li&gt;
&lt;li&gt;Permissions updated&lt;/li&gt;
&lt;li&gt;Token expired&lt;/li&gt;
&lt;li&gt;Cart became non-empty&lt;/li&gt;
&lt;li&gt;Analytics tracking&lt;/li&gt;
&lt;li&gt;Background synchronization&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>reactnative</category>
      <category>100daysofreactnative</category>
    </item>
    <item>
      <title>1 RN Thing a Day – Day 13: Redux Thunk</title>
      <dc:creator>Ola Abaza</dc:creator>
      <pubDate>Fri, 15 May 2026 20:15:52 +0000</pubDate>
      <link>https://dev.to/ola_1313/1-rn-thing-a-day-day-13-redux-thunk-209i</link>
      <guid>https://dev.to/ola_1313/1-rn-thing-a-day-day-13-redux-thunk-209i</guid>
      <description>&lt;p&gt;&lt;strong&gt;What Is Redux Thunk?&lt;/strong&gt;&lt;br&gt;
Redux Thunk is a middleware for Redux that allows you to write action creators that return a function instead of a plain action object.&lt;/p&gt;



&lt;p&gt;Normally, Redux actions look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SET_USER&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;async code doesn't work directly: Redux would throw an error because it expects an object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;dispatch&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="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;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;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUser&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;But with thunk, you can return a function:&lt;br&gt;
&lt;/p&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;fetchUser&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;// Return an async function that receives dispatch as parameter&lt;/span&gt;
  &lt;span class="k"&gt;return&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;dispatch&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;response&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;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SET_USER&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&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="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;&lt;code&gt;Thunk acts as the bridge between async operations and Redux state updates.&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem Without Thunk&lt;/strong&gt;&lt;br&gt;
Imagine handling login directly inside a screen:&lt;br&gt;
&lt;/p&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;handleLogin&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="nf"&gt;setLoading&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;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;response&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;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LOGIN_SUCCESS&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&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="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;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;setLoading&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;This approach causes problems:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Components become bloated&lt;/li&gt;
&lt;li&gt;Logic is duplicated&lt;/li&gt;
&lt;li&gt;Reusability decreases&lt;/li&gt;
&lt;li&gt;Testing becomes harder&lt;/li&gt;
&lt;li&gt;UI and business logic become tightly coupled&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Same Logic Using Thunk:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loginUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&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;return&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;dispatch&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="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setLoading&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;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;response&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;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;loginSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&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="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;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;loginError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setLoading&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="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;Then inside the component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;loginUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Now the component becomes clean and focused only on UI.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Redux Toolkit createAsyncThunk&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modern Redux apps should prefer Redux Toolkit. Instead of manually writing thunk boilerplate.&lt;/p&gt;

&lt;p&gt;The Structure Usually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service Layer: Handles API only.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// services/userService.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getProducts&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;API_URL&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;ul&gt;
&lt;li&gt;Thunk Layer: Handles async Redux logic.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// store/thunks/userThunk.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchProducts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createAsyncThunk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products/fetchProducts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// action type prefix. // sliceName/actionName&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;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getProducts&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;&lt;code&gt;"products/fetchProducts" It is simply:a unique Redux action identifier prefix used to generate async action types automatically.&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slice Layer: Handles state updates.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createSlice&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@reduxjs/toolkit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fetchProducts&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./productThunk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;productSlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSlice&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="na"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="na"&gt;loading&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="na"&gt;error&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="na"&gt;reducers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;

  &lt;span class="na"&gt;extraReducers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;builder&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;builder&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetchProducts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pending&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&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;loading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;

      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetchProducts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fulfilled&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="nx"&gt;action&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;//internally matches:products/fetchProducts/fulfilled&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;loading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&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;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;

      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetchProducts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rejected&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="nx"&gt;action&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&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;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;productSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cleaner syntax&lt;/li&gt;
&lt;li&gt;Built-in pending/fulfilled/rejected states&lt;/li&gt;
&lt;li&gt;Less boilerplate&lt;/li&gt;
&lt;li&gt;Better TypeScript support&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important Concept&lt;/strong&gt;&lt;br&gt;
createAsyncThunk is NOT mainly about API calls.&lt;br&gt;
It is about:&lt;br&gt;
Managing async operations that affect global state. API calls are just the most common example.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Better understanding:&lt;/strong&gt;&lt;br&gt;
Thunk = async business logic connected to Redux state&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That business logic may include:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API calls&lt;/li&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;conditional fetching&lt;/li&gt;
&lt;li&gt;retries&lt;/li&gt;
&lt;li&gt;authentication&lt;/li&gt;
&lt;li&gt;reading current state&lt;/li&gt;
&lt;li&gt;dispatching multiple actions&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>100daysofreactnative</category>
      <category>reactnative</category>
      <category>redux</category>
    </item>
    <item>
      <title>1 RN Thing a Day – Day 12: useEffect vs useFocusEffect</title>
      <dc:creator>Ola Abaza</dc:creator>
      <pubDate>Tue, 21 Apr 2026 09:06:31 +0000</pubDate>
      <link>https://dev.to/ola_1313/1-rn-thing-a-day-day-12-useeffect-vs-usefocuseffect-2b00</link>
      <guid>https://dev.to/ola_1313/1-rn-thing-a-day-day-12-useeffect-vs-usefocuseffect-2b00</guid>
      <description>&lt;p&gt;&lt;strong&gt;useEffect&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React to data changes only&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&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="c1"&gt;// logic&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;dep&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;✅ Runs when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The component mounts&lt;/li&gt;
&lt;li&gt;The dependency (dep) changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;❌ Does NOT run when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The screen is revisited (focused again)&lt;/li&gt;
&lt;li&gt;Navigation happens without changing the dependency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;useFocusEffect&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useFocusEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;useCallback&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;// logic&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;dep&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;✅ Runs when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The screen becomes focused (opened or revisited)&lt;/li&gt;
&lt;li&gt;The dependency changes while the screen is focused&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Even if dep did NOT change → it still runs on screen focus&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;🚨 Common Pitfall&lt;/p&gt;

&lt;p&gt;Using useFocusEffect without resetting state or params:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// will trigger EVERY time screen is focused&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 This can cause repeated side effects or bugs&lt;/p&gt;

&lt;p&gt;✅ Best Practice&lt;/p&gt;

&lt;p&gt;When using navigation params:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useFocusEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;useCallback&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="nf"&gt;handleSideEffect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// reset param to avoid repeated triggers&lt;/span&gt;
    &lt;span class="nx"&gt;NavigationFunctions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setParams&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;isError&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="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isError&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>100daysofreactnative</category>
      <category>useeffect</category>
      <category>lifecycle</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>1 RN Thing a Day – Day 11: When Is await Unnecessary?</title>
      <dc:creator>Ola Abaza</dc:creator>
      <pubDate>Tue, 10 Feb 2026 14:57:54 +0000</pubDate>
      <link>https://dev.to/ola_1313/1-rn-thing-a-day-day-11-when-is-await-unnecessary-4j33</link>
      <guid>https://dev.to/ola_1313/1-rn-thing-a-day-day-11-when-is-await-unnecessary-4j33</guid>
      <description>&lt;p&gt;&lt;strong&gt;The Basic Rule&lt;/strong&gt;&lt;br&gt;
Inside an async function:&lt;/p&gt;

&lt;p&gt;👉 If you are just returning a Promise, you do NOT need await.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple Example&lt;/strong&gt;&lt;br&gt;
Look at these two functions:&lt;/p&gt;

&lt;p&gt;Version 1&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function getData() {
  return await fetchData()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Version 2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function getData() {
  return fetchData()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both functions do exactly the same thing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They return a Promise&lt;/li&gt;
&lt;li&gt;They resolve to the same value&lt;/li&gt;
&lt;li&gt;No behavior difference&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So in Version 1, the await is unnecessary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why This Works&lt;/strong&gt;&lt;br&gt;
An async function automatically wraps its return value in a Promise.&lt;/p&gt;

&lt;p&gt;So when you write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return fetchData()

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

&lt;/div&gt;



&lt;p&gt;JavaScript already knows it’s a Promise and returns it correctly.&lt;/p&gt;

&lt;p&gt;Adding await just waits for the Promise and then returns the same result—without any benefit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When await IS Needed&lt;/strong&gt;&lt;br&gt;
You need await only when you actually want to use the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function getUserName() {
  const user = await fetchUser()
  return user.name
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here await is required because you need to access user.name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Easy Rule to Remember&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use await when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need the resolved value&lt;/li&gt;
&lt;li&gt;You want to do logic with the result&lt;/li&gt;
&lt;li&gt;You have multiple async steps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Skip await when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You are only returning a Promise&lt;/li&gt;
&lt;li&gt;No extra logic is needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;br&gt;
Inside an async function:&lt;br&gt;
👉 If you are only returning a Promise, don’t use await.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>100daysofreactnative</category>
    </item>
    <item>
      <title>1 RN Thing a Day – Day 10: Memoization in React Native</title>
      <dc:creator>Ola Abaza</dc:creator>
      <pubDate>Sat, 30 Aug 2025 13:03:13 +0000</pubDate>
      <link>https://dev.to/ola_1313/1-rn-thing-a-day-day-10-memoization-in-react-native-45lp</link>
      <guid>https://dev.to/ola_1313/1-rn-thing-a-day-day-10-memoization-in-react-native-45lp</guid>
      <description>&lt;p&gt;It is an optimization technique used to improve performance by caching the results of expensive function calls or avoiding unnecessary re-renders of components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to use memoization effectively in React Native:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Memoizing Components with React.memo
React.memo is used to prevent unnecessary re-renders of functional components when their props do not change.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';

const ExpensiveComponent = React.memo(({ data }) =&amp;gt; {
  console.log('Rendering ExpensiveComponent');
  return &amp;lt;Text&amp;gt;{data}&amp;lt;/Text&amp;gt;;
});

// Parent component
const App = () =&amp;gt; {
  const [count, setCount] = React.useState(0);
  return (
    &amp;lt;&amp;gt;
      &amp;lt;ExpensiveComponent data="This won't re-render" /&amp;gt;
      &amp;lt;Button title="Increment" onPress={() =&amp;gt; setCount(count + 1)} /&amp;gt;
    &amp;lt;/&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;p&gt;In this example, ExpensiveComponent only re-renders if its data prop changes.&lt;/p&gt;

&lt;p&gt;2.Memoizing Values with useMemo&lt;br&gt;
useMemo caches the result of an expensive computation so that it does not need to be recalculated unless its dependencies change.&lt;br&gt;
&lt;/p&gt;

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

const App = () =&amp;gt; {
  const [count, setCount] = React.useState(0);

  const expensiveCalculation = useMemo(() =&amp;gt; {
    console.log('Performing expensive calculation');
    return count * 2;
  }, [count]);

  return (
    &amp;lt;&amp;gt;
      &amp;lt;Text&amp;gt;Result: {expensiveCalculation}&amp;lt;/Text&amp;gt;
      &amp;lt;Button title="Increment" onPress={() =&amp;gt; setCount(count + 1)} /&amp;gt;
    &amp;lt;/&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;p&gt;3.Memoizing Functions with useCallback&lt;br&gt;
useCallback memoizes a function to avoid re-creating it on every render, especially when passing it as a prop to child components.&lt;br&gt;
&lt;/p&gt;

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

const Button = React.memo(({ onPress }) =&amp;gt; {
  console.log('Rendering Button');
  return &amp;lt;TouchableOpacity onPress={onPress}&amp;gt;&amp;lt;Text&amp;gt;Press Me&amp;lt;/Text&amp;gt;&amp;lt;/TouchableOpacity&amp;gt;;
});

const App = () =&amp;gt; {
  const [count, setCount] = useState(0);

 // without useCallback the onPress prop changed (new function reference), so I need to re-render &amp;lt;Button /&amp;gt;

  const increment = useCallback(() =&amp;gt; {
    setCount(prev =&amp;gt; prev + 1);
  }, []);

  return (
    &amp;lt;&amp;gt;
      &amp;lt;Text&amp;gt;Count: {count}&amp;lt;/Text&amp;gt;
      &amp;lt;Button onPress={increment} /&amp;gt;
    &amp;lt;/&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;p&gt;Without useCallback, the increment function would be re-created on every render, causing the Button component to re-render unnecessarily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem without useCallback&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In React, functions are objects.&lt;br&gt;
Every time your component re-renders, any inline function you create gets a new reference in memory even if the logic is identical.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoid Overusing Memoization&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid memoizing components or values that are inexpensive to compute.&lt;/li&gt;
&lt;li&gt;Use profiling tools (e.g., React DevTools Profiler) to identify performance bottlenecks before applying memoization.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Memoization Libraries&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In some cases, you might want to use libraries like memoize-one or lodash.memoize for custom memoization needs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import memoize from 'lodash.memoize';

const memoizedFunction = memoize(expensiveFunction);

function expensiveFunction(arg) {
  console.log('Calculating...');
  return arg * 2;
}

console.log(memoizedFunction(2)); // "Calculating..." -&amp;gt; 4
console.log(memoizedFunction(2)); // Cached result -&amp;gt; 4

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

&lt;/div&gt;



&lt;p&gt;lodash.memoize keeps a cache of results for each unique input key you pass in.&lt;/p&gt;

&lt;p&gt;useMemo (React) doesn’t store results for every input ever passed.&lt;br&gt;
It only remembers the last computation tied to its dependency array.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What memoization does under the hood&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you use React.memo, useMemo, or useCallback, React has to:&lt;/li&gt;
&lt;li&gt;Store the previous value (or component render).&lt;/li&gt;
&lt;li&gt;Compare the current props/values with the previous ones (a shallow comparison).&lt;/li&gt;
&lt;li&gt;Decide whether to re-render or return the cached result.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This bookkeeping work itself takes CPU time and memory.&lt;/p&gt;

&lt;p&gt;If the component or calculation is very cheap (e.g., rendering a single  or calculating a + b), then:&lt;br&gt;
Re-rendering or recalculating is often faster than doing all the memoization checks.&lt;br&gt;
Adding memoization in such cases can slow things down instead of speeding them up&lt;/p&gt;

&lt;p&gt;Always measure (with React DevTools Profiler) before and after, to confirm the performance gain.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>reactnative</category>
      <category>memoization</category>
      <category>100daysofreactnative</category>
      <category>performance</category>
    </item>
    <item>
      <title>1 RN Thing a Day – Day 9: Animated API</title>
      <dc:creator>Ola Abaza</dc:creator>
      <pubDate>Mon, 18 Aug 2025 20:09:55 +0000</pubDate>
      <link>https://dev.to/ola_1313/1-rn-thing-a-day-day-9-animated-api-2i72</link>
      <guid>https://dev.to/ola_1313/1-rn-thing-a-day-day-9-animated-api-2i72</guid>
      <description>&lt;p&gt;In React Native, the Animated API is used because it gives you a performant and flexible way to create animations in your app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔑 Reasons to Use the Animated API&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;br&gt;
If you animate with setState, every frame causes a full React render, which is slow.The Animated API runs animations on the native UI thread (especially with useNativeDriver: true), so animations stay smooth (60fps)(frames per second) even if JavaScript is busy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Declarative Animations&lt;/strong&gt;&lt;br&gt;
You describe what should happen (e.g., "move this box from X=0 to X=200 over 500ms"), and React Native handles the how. Makes animations easier to reason about.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reusability&lt;/strong&gt;&lt;br&gt;
The same Animated.Value can drive multiple properties (opacity, scale, rotation, etc.). Easier than manually tracking multiple states.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gestures + Physics&lt;/strong&gt;&lt;br&gt;
Supports spring animations, decay (momentum), and interactions with touch gestures. Perfect for natural-feeling UI like swipes, drags, and bounces.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cross-Platform Consistency&lt;/strong&gt;&lt;br&gt;
Works on both iOS and Android with the same API, without you needing to use native code for animations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interpolation&lt;/strong&gt;&lt;br&gt;
You can map one animated value into different ranges. Example:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const progress = useRef(new Animated.Value(0)).current;

// Slide horizontally
const translateX = progress.interpolate({
  inputRange: [0, 1],
  outputRange: [0, 200],
});

// Fade out
const opacity = progress.interpolate({
  inputRange: [0, 0.5, 1],
  outputRange: [1, 0.5, 0],  // custom curve
});

// Rotate
const rotate = progress.interpolate({
  inputRange: [0, 1],
  outputRange: ["0deg", "360deg"],
});

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;All are derived from the same progress value.&lt;br&gt;
→ This allows chaining multiple visual effects from one value.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🔹 Step by step&lt;/strong&gt; (useRef(new Animated.Value(0)).current;)&lt;br&gt;
1- new Animated.Value(0)&lt;br&gt;
Creates an Animated.Value object starting at 0.&lt;br&gt;
This is the special type React Native uses to drive animations (instead of a normal number).&lt;/p&gt;

&lt;p&gt;2- useRef(...)&lt;br&gt;
Ensures the value is persistent across re-renders.&lt;br&gt;
Without useRef, every re-render would create a new Animated.Value, resetting the animation back to 0.&lt;br&gt;
With useRef, React will keep the same object during the component’s lifecycle.&lt;/p&gt;

&lt;p&gt;3- .current&lt;br&gt;
useRef returns an object like { current:  }.&lt;br&gt;
.current gives you the actual Animated.Value stored inside.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useRef, useEffect } from "react";
import { Animated, View } from "react-native";

export default function Box() {
  const fadeAnim = useRef(new Animated.Value(0)).current; // start opacity at 0

  useEffect(() =&amp;gt; {
    Animated.timing(fadeAnim, {
      toValue: 1,
      duration: 2000,
      useNativeDriver: true, // run on UI thread
    }).start();
  }, []);

  return (
    &amp;lt;Animated.View
      style={{
        opacity: fadeAnim,
        width: 100,
        height: 100,
        backgroundColor: "blue",
      }}
    /&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;👉 Without Animated, you'd have to manually update opacity on every frame — very inefficient.&lt;/p&gt;

&lt;p&gt;✅ In short:&lt;br&gt;
We need the Animated API in React Native because it makes animations smooth, efficient, declarative, and easy to combine with gestures and physics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔹 What happens with setState?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you call setState, React re-renders in the JS thread.&lt;/li&gt;
&lt;li&gt;That means every frame of the animation depends on the JS thread being free and fast.&lt;/li&gt;
&lt;li&gt;If the JS thread is busy (fetching API, parsing JSON, rendering a heavy component), the animation drops frames → stutters.&lt;/li&gt;
&lt;li&gt;That’s why animations with setState often run at 30fps or less, instead of smooth 60fps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;⚖️ Quick Comparison between Animated(built-in) and react-native-reanimated&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Performance --&amp;gt; Good, but JS can block --&amp;gt; Excellent (runs on UI thread)&lt;/li&gt;
&lt;li&gt;Complexity handling --&amp;gt; Basic animations only --&amp;gt; Handles very complex flows&lt;/li&gt;
&lt;li&gt;Gesture support --&amp;gt; Limited --&amp;gt; designed to work seamlessly with react-native-gesture-handler.&lt;/li&gt;
&lt;li&gt;Ease of use --&amp;gt; Simple API --&amp;gt; Steeper learning curve&lt;/li&gt;
&lt;li&gt;Dependencies --&amp;gt; Built-in (no install) --&amp;gt; Requires installation &amp;amp; setup&lt;/li&gt;
&lt;li&gt;Recommended for production --&amp;gt; Small/simple apps --&amp;gt; Medium/large apps with rich UI&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>100daysofreactnative</category>
      <category>reactnative</category>
      <category>animation</category>
    </item>
    <item>
      <title>1 RN Thing a Day – Day 8: Trivyignore</title>
      <dc:creator>Ola Abaza</dc:creator>
      <pubDate>Sun, 17 Aug 2025 22:58:44 +0000</pubDate>
      <link>https://dev.to/ola_1313/1-rn-thing-a-day-day-8-trivyignore-343d</link>
      <guid>https://dev.to/ola_1313/1-rn-thing-a-day-day-8-trivyignore-343d</guid>
      <description>&lt;p&gt;.trivyignore is a configuration file used by Trivy, an open-source vulnerability scanner for containers, Kubernetes, and other dependencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔹 Containers&lt;/strong&gt;&lt;br&gt;
A container is a lightweight, standalone package that includes:&lt;br&gt;
The application code (e.g., your React Native backend service, or a Node.js API)&lt;/p&gt;

&lt;p&gt;Its dependencies (libraries, runtimes like Node.js, Python, Java, etc.)&lt;br&gt;
The OS-level binaries needed to run&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 Think of it like a zip file that has everything your app needs so it runs the same way on any machine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🔹 Kubernetes (K8s)&lt;/strong&gt;3&lt;br&gt;
Kubernetes is a system that helps you run and manage containers across multiple machines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Kubernetes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You describe what you want (e.g., "I need 5 containers of my RN backend always running").&lt;/li&gt;
&lt;li&gt;Kubernetes automatically deploys, scales, heals, and load-balances containers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Think of it like a container orchestrator or a "manager for containers."&lt;/p&gt;

&lt;p&gt;📌 Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You write a YAML file (deployment.yaml) that says:&lt;/li&gt;
&lt;li&gt;Run 5 replicas of my RN backend container.&lt;/li&gt;
&lt;li&gt;Expose them via a service on port 3000.&lt;/li&gt;
&lt;li&gt;Kubernetes ensures those 5 are always running. If one dies → it restarts it.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Container = a package of your app + everything it needs to run.&lt;br&gt;
Kubernetes = a system that runs and manages lots of containers reliably.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;What is Trivy?&lt;/strong&gt;&lt;br&gt;
Trivy is a security scanning tool developed by Aqua Security that detects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OS package vulnerabilities (e.g., in Alpine, Debian, Ubuntu)&lt;/li&gt;
&lt;li&gt;Application dependencies vulnerabilities (e.g., npm, pip, Maven)&lt;/li&gt;
&lt;li&gt;Container image vulnerabilities&lt;/li&gt;
&lt;li&gt;Infrastructure as Code (IaC) misconfigurations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is .trivyignore?&lt;/strong&gt;&lt;br&gt;
.trivyignore is a file that allows you to ignore specific vulnerabilities found by Trivy. This is useful when you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Acknowledge a vulnerability but determine it doesn’t affect your project.&lt;/li&gt;
&lt;li&gt;Are waiting for an upstream fix and want to suppress noise.&lt;/li&gt;
&lt;li&gt;Need to whitelist known issues for compliance reasons.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How to use .trivyignore?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a .trivyignore file in your project root.&lt;/li&gt;
&lt;li&gt;Add the vulnerability IDs you want to ignore.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CVE-2022-1234
CVE-2021-5678
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Trivy will skip reporting these vulnerabilities in scans.&lt;/p&gt;

</description>
      <category>trivyignore</category>
      <category>reactnative</category>
      <category>100daysofreactnative</category>
    </item>
    <item>
      <title>1 RN Thing a Day – Day 7: KeyboardAwareScrollView</title>
      <dc:creator>Ola Abaza</dc:creator>
      <pubDate>Mon, 11 Aug 2025 21:58:09 +0000</pubDate>
      <link>https://dev.to/ola_1313/1-rn-thing-a-day-day-7-keyboardawarescrollview-1mhm</link>
      <guid>https://dev.to/ola_1313/1-rn-thing-a-day-day-7-keyboardawarescrollview-1mhm</guid>
      <description>&lt;p&gt;&lt;strong&gt;KeyboardAwareScrollView&lt;/strong&gt; is a component from the react-native-keyboard-aware-scroll-view library that helps handle keyboard interactions in React Native. It ensures that input fields remain visible when the keyboard appears, preventing them from being covered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;:&lt;br&gt;
Here's a simple example of how to use KeyboardAwareScrollView:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { TextInput, View, Text } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';

const MyScreen = () =&amp;gt; {
  return (
    &amp;lt;KeyboardAwareScrollView
      style={{ flex: 1, padding: 16 }}
      contentContainerStyle={{ flexGrow: 1 }}
      enableOnAndroid={false} //  true by default
      extraScrollHeight={0} // Adjusts scrolling space when the keyboard  is open , 75 by default
      keyboardShouldPersistTaps="handled" //"never" by default
      showsVerticalScrollIndicator: false
      bounces: false
    &amp;gt;
      &amp;lt;View&amp;gt;
        &amp;lt;Text&amp;gt;Enter your details:&amp;lt;/Text&amp;gt;
        &amp;lt;TextInput
          placeholder="Type here..."
          style={{
            height: 50,
            borderWidth: 1,
            borderColor: '#ccc',
            marginVertical: 10,
            paddingHorizontal: 10,
          }}
        /&amp;gt;
      &amp;lt;/View&amp;gt;
    &amp;lt;/KeyboardAwareScrollView&amp;gt;
  );
};

export default MyScreen;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Props:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;enableOnAndroid={false}: Disables keyboard awareness on Android. If you need input fields to move up when the keyboard appears, you might want this set to true.&lt;/li&gt;
&lt;li&gt;extraScrollHeight={0}: No additional space is added when the keyboard appears. If inputs get covered, consider increasing this value (e.g., extraScrollHeight: 20).&lt;/li&gt;
&lt;li&gt;keyboardShouldPersistTaps=" handled": Allows taps on the screen to dismiss the keyboard.&lt;/li&gt;
&lt;li&gt;showsVerticalScrollIndicator: "false": Hides the vertical scrollbar, which might be good for a cleaner&lt;/li&gt;
&lt;li&gt;contentContainerStyle={{ flexGrow: 1 }}: Ensures content is scrollable when necessary.&lt;/li&gt;
&lt;li&gt;bounces: "false": Prevents the slight bounce effect when reaching the top or bottom of the scrollable content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;List of other common KeyboardAwareScrollView props:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;enableAutomaticScroll – true (will scroll automatically to focused input).&lt;/li&gt;
&lt;li&gt;extraHeight – 0 (no extra height unless set).&lt;/li&gt;
&lt;li&gt;keyboardOpeningTime – 250 (ms delay before scrolling).&lt;/li&gt;
&lt;li&gt;viewIsInsideTabBar – false (no adjustment unless inside tab bar).&lt;/li&gt;
&lt;li&gt;enableResetScrollToCoords – true (scroll resets when keyboard hides).&lt;/li&gt;
&lt;li&gt;contentContainerStyle – undefined (no default styles).&lt;/li&gt;
&lt;li&gt;showsVerticalScrollIndicator – true (scroll bar visible).&lt;/li&gt;
&lt;li&gt;bounces – true (scroll view bounces at edges).&lt;/li&gt;
&lt;li&gt;horizontal – false (scrolls vertically by default).&lt;/li&gt;
&lt;li&gt;onScroll – undefined (no default scroll handler).&lt;/li&gt;
&lt;li&gt;pagingEnabled – false (no page snapping).&lt;/li&gt;
&lt;li&gt;onKeyboardWillShow – undefined (no default event handler).&lt;/li&gt;
&lt;li&gt;onKeyboardDidShow – undefined (no default event handler).&lt;/li&gt;
&lt;li&gt;onKeyboardWillHide – undefined (no default event handler).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If you don’t use KeyboardAwareScrollView:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input fields near the bottom may get covered by the keyboard.&lt;/li&gt;
&lt;li&gt;You’ll need to manually handle keyboard show/hide events.&lt;/li&gt;
&lt;li&gt;Scrolling to bring inputs into view won’t happen automatically.&lt;/li&gt;
&lt;li&gt;Different behavior on iOS vs Android may cause inconsistent UX.&lt;/li&gt;
&lt;li&gt;User may need to manually scroll to see what they’re typing.&lt;/li&gt;
&lt;li&gt;Small-screen devices will have worse usability.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>reactnative</category>
      <category>keyboardawarescrollview</category>
      <category>100daysofreactnative</category>
    </item>
    <item>
      <title>1 RN Thing a Day – Day 6: Shallow Copy vs. Deep Copy</title>
      <dc:creator>Ola Abaza</dc:creator>
      <pubDate>Sat, 09 Aug 2025 18:27:36 +0000</pubDate>
      <link>https://dev.to/ola_1313/1-rn-thing-a-day-day-6-shallow-copy-vs-deep-copy-29a1</link>
      <guid>https://dev.to/ola_1313/1-rn-thing-a-day-day-6-shallow-copy-vs-deep-copy-29a1</guid>
      <description>&lt;p&gt;&lt;strong&gt;Example: Shallow Copy vs. Deep Copy&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import cloneDeep from 'lodash/cloneDeep';

const original = [
  { id: 1, info: { status: "active" } },
  { id: 2, info: { status: "inactive" } }
];

// Shallow copy
const shallowCopy = original.slice();
shallowCopy[0].info.status = "changed";
console.log(original[0].info.status); // "changed" (still linked)

// Deep copy
const deepCopy = cloneDeep(original);
deepCopy[0].info.status = "changed again";
console.log(original[0].info.status); // "changed" (original unaffected)
console.log(deepCopy[0].info.status); // "changed again"

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;cloneDeep&lt;/strong&gt; from Lodash recursively walks through the structure of your object or array and:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creates new objects/arrays instead of reusing existing ones.&lt;/li&gt;
&lt;li&gt;Copies primitive values (string, number, boolean) directly.&lt;/li&gt;
&lt;li&gt;Handles special types (Date, Map, Set, RegExp, Buffer, TypedArrays).&lt;/li&gt;
&lt;li&gt;Supports circular references (won’t get stuck in infinite recursion).&lt;/li&gt;
&lt;li&gt;Preserves property descriptors, prototype chains, and symbols.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The Core Problem It Solves&lt;/strong&gt;&lt;br&gt;
In JavaScript, objects and arrays are reference types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const a = { name: "Ola" };
const b = a; // just a reference, not a copy

b.name = "Changed";

console.log(a.name); // Changed 😱
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, a and b are pointing to the same object in memory.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you try to "copy" an array of objects using things like .slice() or .filter(), you only copy the outer array, not the inner objects.&lt;br&gt;
So you still have shared references to the nested objects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;When You Should Use cloneDeep:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Transformations&lt;/strong&gt;: You’re modifying data but want the original untouched.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redux state&lt;/strong&gt;: Avoid accidental mutation of state objects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test data&lt;/strong&gt;: Copy fixtures so each test gets a fresh, isolated version.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Breaking shared references&lt;/strong&gt;: When two lists should contain separate but identical-looking objects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When You Should Use a Shallow Copy:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The data does not contain nested objects/arrays that we care about mutating independently.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Or when we only need to change the outer layer of the structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Arrays of primitives&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nums = [1, 2, 3];
const copy = nums.slice(); // shallow copy

copy[0] = 99;

console.log(nums); // [1, 2, 3] ✅ unaffected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Primitives (numbers, strings, booleans) are copied by value,&lt;br&gt;
so shared references aren’t a problem.&lt;/p&gt;

&lt;p&gt;_"Copied by value" means_When you assign or copy a primitive, JavaScript copies the actual value, not a reference to it.&lt;br&gt;
So changes to one variable do not affect the other.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Short-lived transformations
If you just need a quick copy to sort, filter, or reverse the outer array but don’t care about mutating the nested items later:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const people = [{ name: "Ola" }, { name: "Ali" }];

// Just sorting names
const sorted = [...people].sort((a, b) =&amp;gt; a.name.localeCompare(b.name));

console.log(sorted[0] === people[0]); // true (same reference inside)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Sorting changes only the array order, not the inner objects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Replacing the top-level object
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const state = { count: 0, user: { name: "Ola" } };

// Only replacing user object
const newState = { ...state, user: { name: "John" } };

console.log(state.user.name); // Ola ✅ unchanged
console.log(newState.user.name); // John
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Here, we create a new outer object but explicitly replace the nested one.&lt;br&gt;
No need to deep clone the whole thing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;💡&lt;strong&gt;Rule of Thumb:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If the structure has no nested objects/arrays that will be mutated independently,&lt;br&gt;
or if you will replace nested data entirely instead of mutating it,&lt;br&gt;
then a shallow copy is fine.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>100daysofreactnative</category>
      <category>reactnative</category>
      <category>javascript</category>
    </item>
    <item>
      <title>1 RN Thing a Day – Day 5: Usage of _partition</title>
      <dc:creator>Ola Abaza</dc:creator>
      <pubDate>Fri, 08 Aug 2025 15:28:48 +0000</pubDate>
      <link>https://dev.to/ola_1313/1-rn-thing-a-day-day-5-usage-of-partition-2857</link>
      <guid>https://dev.to/ola_1313/1-rn-thing-a-day-day-5-usage-of-partition-2857</guid>
      <description>&lt;p&gt;— partition is a function from the Lodash library.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What _.partition does&lt;/strong&gt;&lt;br&gt;
.partition(collection, predicate)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes an array (collection) and a predicate function (a condition).&lt;/li&gt;
&lt;li&gt;Splits the array into two sub-arrays:

&lt;ul&gt;
&lt;li&gt;First array → all elements where the predicate returns true&lt;/li&gt;
&lt;li&gt;Second array → all elements where the predicate returns false&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Returns them as a 2-element array: [matches, nonMatches].&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const assets = [
  { name: 'iPhone', assetType: 'Device' },
  { name: 'Netflix', assetType: 'Subscription' },
  { name: 'iPad', assetType: 'Device' }
];

const [devices, subs] = _.partition(
  assets,
  asset =&amp;gt; asset.assetType === 'Device'
);

console.log(devices);
// [{ name: 'iPhone', assetType: 'Device' }, { name: 'iPad', assetType: 'Device' }]

console.log(subs);
// [{ name: 'Netflix', assetType: 'Subscription' }]


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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it’s different from .filter()&lt;/strong&gt;&lt;br&gt;
If you used .filter() twice like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const truthy = arr.filter(x =&amp;gt; condition(x));
const falsy = arr.filter(x =&amp;gt; !condition(x));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’d loop through the array two times.&lt;br&gt;
_.partition does it in one loop more efficient.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>100daysofreactnative</category>
      <category>lodash</category>
    </item>
    <item>
      <title>1 RN Thing a Day – Day 4: Usage of omitBy</title>
      <dc:creator>Ola Abaza</dc:creator>
      <pubDate>Fri, 08 Aug 2025 15:15:53 +0000</pubDate>
      <link>https://dev.to/ola_1313/1-rn-thing-a-day-day-4-usage-of-omitby-4lif</link>
      <guid>https://dev.to/ola_1313/1-rn-thing-a-day-day-4-usage-of-omitby-4lif</guid>
      <description>&lt;p&gt;In Lodash, _.omitBy creates a new object by removing properties where the predicate function returns true.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;_.omitBy is only for objects (key–value pairs), not for arrays of values.&lt;br&gt;
If you have an object → use omitBy (removes properties based on a condition) or pickBy (Keeps properties based on a condition).&lt;br&gt;
If you have an array → use filter (removes items based on a condition) or map (transforms each item).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;What omitBy Does&lt;/strong&gt;&lt;br&gt;
_.omitBy(object, predicate)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loops over each property of the given object.&lt;/li&gt;
&lt;li&gt;Runs your predicate function for every (value, key).&lt;/li&gt;
&lt;li&gt;If predicate returns true, that property is removed from the new object.&lt;/li&gt;
&lt;li&gt;Returns a new object (does not modify the original).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as the opposite of _.pickBy — instead of keeping matching properties, you remove them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Basic Example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import omitBy from 'lodash/omitBy';

const obj = {
  name: 'Ola',
  age: 0,
  active: false,
  city: null
};

const result = omitBy(obj, (value) =&amp;gt; value == null);
// removes `null` and `undefined`

console.log(result);
// { name: 'Ola', age: 0, active: false }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How the Predicate Works&lt;/strong&gt;&lt;br&gt;
The predicate gets two arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(value, key) =&amp;gt; {
  // value → the property value
  // key   → the property key as a string
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;omitBy(obj, (value, key) =&amp;gt; key === 'age');
// removes any property where the key is "age"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Common Uses&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove null or undefined fields
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;omitBy(obj, value =&amp;gt; value == null);

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Remove all falsy values (false, 0, '', null, undefined, NaN)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;omitBy(obj, value =&amp;gt; !value);

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Remove keys by name pattern
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;omitBy(obj, (value, key) =&amp;gt; key.startsWith('_'));
// removes any key starting with underscore

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Difference from omit&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;omit → remove by key names you already know:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**_.omit(obj, ['age', 'city']);*

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;omitBy → remove by a condition (calculated dynamically for each key).&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>reactnative</category>
      <category>100daysofreactnative</category>
      <category>lodash</category>
    </item>
  </channel>
</rss>
