title: React (Native) Context API Causes Stack Navigator (React Navigation 5) to re-render after state update
body: <p>Thanks in advance for helping with this question.</p>
  <hr />
  <h1>Some Context (No Pun Intended)</h1>
  <p>I'm working on a company's project that will restrict me from putting all the code on here, but I will try and put as much relevant code as I can without revealing state secrets.</p>
  <p>Basically, the React Native app is using React Navigation v5 and I've been trying to figure this problem out for two days. I understand what is happening, but I don't understand why its happening or how to fix it.</p>
  <p>Somewhere inside the app code, you have the below code.</p>
  <pre><code>export const Lounge = function Lounge(props: {navigation: any}) {
    
    const {navigation: {setOptions}} = props
    const bottomTabBarCtx = useContext(BottomTabBarContext)
  
    // const [routeName, setRouteName] = useState(&quot;LoungeList&quot;)
  
    useEffect(() =&gt; {
      setOptions({tabBarVisible: bottomTabBarCtx.isVisible})
    }, [bottomTabBarCtx.isVisible, setOptions])
  
    return &lt;Stack.Navigator initialRouteName={&quot;LoungeList&quot;}&gt;
      &lt;Stack.Screen
        name=&quot;LoungeList&quot;
        component={List}
        options={{headerShown: false}}
      /&gt;
  
      &lt;Stack.Screen
        name=&quot;LoungeDetails&quot;
        component={Details}
        options={{
          headerLeft : buttonProps =&gt; &lt;BackButton {...buttonProps} /&gt;,
          headerRight: buttonProps =&gt; &lt;LoungeHeaderRightDetailsButton {...buttonProps} /&gt;,
          headerTitle: 'Lounge Details',
        }}
      /&gt;
  
      &lt;Stack.Screen
        name=&quot;LoungeParticipants&quot;
        component={Participants}
  
        options={{
          headerLeft : buttonProps =&gt; &lt;BackButton {...buttonProps} /&gt;,
          headerRight: buttonProps =&gt; &lt;LoungeHeaderRightDetailsButton {...buttonProps} /&gt;,
          headerTitle: 'Lounge Participants',
        }}
      /&gt;
  
      &lt;Stack.Screen
        name=&quot;LoungeAdd&quot;
        component={LoungeEdit}
  
        options={{
          headerLeft : buttonProps =&gt; &lt;BackButton {...buttonProps} /&gt;,
          headerTitle: 'Create Lounge',
        }}
      /&gt;
  
      &lt;Stack.Screen
        name=&quot;LoungeEdit&quot;
        component={LoungeEdit}
  
        options={{
          headerLeft : buttonProps =&gt; &lt;BackButton {...buttonProps} /&gt;,
          headerTitle: 'Edit Lounge',
        }}
      /&gt;
  
  ...
  </code></pre>
  <p>The above file simply defines the routes that can be navigated to in this section of the app.</p>
  <p>The initial screen/route name = <strong>'LoungeList'</strong></p>
  <p>That all works fine.</p>
  <p>From the <strong>LoungeList</strong> screen, I tap on a lounge summary cell (use your imagination please), and that tap takes me to the screen underneath: <strong>LoungeDetails</strong></p>
  <p>Inside the <strong>LoungeDetails</strong> screen, I see the details of the lounge, and on that screen, there is also a <em>Join Button</em>. This button enables me to join the lounge.</p>
  <p>The functionality is supposed to be that, when a user taps on the join button, the button goes into a loading state, and when it has finished loading, it should read <strong>Joined</strong>. This happens as it should <strong>BUT</strong> immediately after this happens <strong>I am navigated to the LoungeList screen</strong></p>
  <p>Below is the code I execute for joining a lounge:</p>
  <pre><code>const userDidJoinLounge = (joinedLounge: LoungeWithUsers) =&gt; {
  
      if(joinedLounge){
  
        console.log(&quot;joinedLounge before update == &quot;, joinedLounge);
        
        const allLoungesNew = LoungeController.replaceLoungeInLoungeArray(
          userCtx.allLoungesList,
          joinedLounge
        );
  
        const userLoungesNew = LoungeController.getUserJoinedLoungeArrayListOnJoin(
          allLoungesNew,
          userCtx.userLoungeList,
          joinedLounge
        );
  
        console.log(&quot;allLounges after update == &quot;, allLoungesNew);
        console.log(&quot;joinedLounges after update == &quot;, userLoungesNew);
  
        userCtx.updateLoungeLists(allLoungesNew, userLoungesNew)
  
      }
    }
  </code></pre>
  <p>In the above function, the line</p>
  <p><code>userCtx.updateLoungeLists(allLoungesNew, userLoungesNew)</code> takes in two parameters, a list of all the lounges on the app, and a list of lounges the user has joined. This function updates the context that holds these two values.</p>
  <hr />
  <h1>THE BIG ISSUE</h1>
  <p><strong>Issue</strong>: <em>I keep getting redirected to the LoungeList screen, even though there isn't any code instructing the app to do that</em>.</p>
  <h2>THINGS THAT MIGHT HELP</h2>
  <p>I've played around with many things and a few things that might help you in figuring out what is going on are:</p>
  <ul>
  <li><p>It seems that the React Navigation route config is being re-rendered. I say this because when I changed the initialRouteName to be <strong>LoungeDetails</strong>, the lounge details screen (where the join button is) flickers, <strong>but it stays on the same screen</strong>. This also tells me, that at the end of that function, the stack navigator falls back to whatever <strong>initialRouteName</strong> is.</p>
  </li>
  <li><p>Wierdly, when I only set <code>allLoungesNew</code> then the app doesn't navigate to <code>initialRouteName</code>, it seems this issue only happens when I set <code>userLoungesNew</code> in the userContext's state.</p>
  </li>
  </ul>
  <h3>How do I stop react-navigation from navigating away from the screen when the user has tapped the join button?</h3>
  <p>Thank you very much for your help. I hope I've given you enough information to solve the problem. Feel free to ask any more questions to help solve the problem. I will tell you what I am allowed to.</p>