Search code examples
typescriptreact-nativecallbackuse-effecttabnavigator

Why are components not rerendering on state change even WITH key change?


I have a custom tab component that I'm using to navigate between tabs with my desired format. One of the tabs has buttons that also need to navigate to these other tabs (not my design, I can't change the content).

Roughly, here's an example of how the navigator is being used:

const [selectedRoute, setSelectedRoute] = useState<string>("TabOne");
const [idle, setIdle] = useState<boolean>(true);

useEffect(() => {
  // Do stuff
}, [idle]);

useEffect(() => {
  // No stuff to do but needs to be declared so that it's handled
  // Logs show that this function is being called and the route is changing
}, [selectedRoute]);

return(
  <SideNavTabsNavigator
    // I have tried setting key={selectedRoute} and STILL no rerender
    selectedRoute={selectedRoute}     // Route name of the tab displayed
    selectRoute={setSelectedRoute}    // Callback that switches tabs (this one works)
    resetTimer={() => setIdle(false)} // Callback that resets an automatic logout timer (this one works)
    routeProps={{
      TabOne: {
        screen:
          <TabOne
            resetTimer={() => setIdle(false)} // Callback that resets an automatic logout timer (this one works because there is no need to rerender)
            selectRoute={setSelectedRoute} // Callback that switches tabs (does NOT work)
            // Have also tried:
            // selectRoute={() => setSelectedRoute}
            // selectRoute={() => setSelectedRoute("TabTwo")} 
            // selectRoute={(routeName: string) => setSelectedRoute(routeName)}
          />,
        icon: "refresh",
        iconLabel: "Tab One",
      },
      TabTwo: {
        screen:
          <TabTwo
            resetTimer={() => setSelectedRoute} // Callback that switches tabs (does NOT work)
            selectRoute={setSelectedRoute} // Callback that switches tabs (does NOT work)
          />,
        icon: "arrow-down-bold-box",
        iconLabel: "Tab Two",
      },
    }}
  />
);

I'm passing a callback to the tabs so that when the button is pressed, the selected route will change. The callback changes the selected route and useEffect is called, but the component is not rerendering, thus not changing the tab.

Here is roughly what SideNavTabsNavigator returns and how it is structured:

<SideNavTabs>
  <SideNavTabs.Tab>
    <SideNavTabs.Icon />
    <TabComponent />
  </SideNavTabs.Tab>
</SideNavTabs>

Changing tabs works perfectly fine from SideNavTabs, but not from routeProps and I have tried so many things but I'm just not sure why it's not working at this point. Any help or explanation would be greatly appreciated.

I'm thinking about just navigating to a completely new navigator component because I can't figure this out, but that seems incredibly inefficient to build an entirely new instance.


Solution

  • I realized somewhere along the lines, I was incorrectly calling the component in the first place. I was populating it somewhere like SideNav(props) instead of <SideNav props={props} />