Search code examples
react-nativereact-navigationreact-navigation-v5

How to decide which component should be rendered dynamically in React Navigation?


This is my structure:

const RootStack = () => ( 
  <Stack.Navigator>
    <Stack.Screen name="Home" component={HomeTabs} />
    <Stack.Screen name="AddNote" component={AddNoteScreen} />
  </Stack.Navigator>
);

const HomeTabs = () => ( 
  <Tab.Navigator>
    <Tab.Screen name="Home" component={HomeStack}/>
    <Tab.Screen name="Customers" component={CustomersStack}/>
  </Tab.Navigator>
);

const HomeStack = () => (
  <Stack.Navigator>
     <Stack.Screen name="Home" component={HomeScreen}/>
     <Stack.Screen name="Tickets" component={TicketsStack}/>
  </Stack.Navigator>
);

const CustomerStack = () => (
  <Stack.Navigator>
     <Stack.Screen name="Customer" component={CustomerScreen}/>
     <Stack.Screen name="Tickets" 
       initialParams={{ parentRouteConfig: true }} 
       component={TicketsStack}
      />
  </Stack.Navigator>
);

const TicketStack = (props) => {
  const { route } = props;
  const { params } = route;

  return (
    <Stack.Navigator> 
      <Stack.Screen 
      name={params?.parentRouteConfig ? 'CustomerTickets' : 'Tickets'}
      component={params?.parentRouteConfig ? CustomerTicketsScreen : TicketsScren} 
      />
      <Stack.Screen name="TicketDetail" component={TicketDetailScreen} />
    </Stack.Navigator>
  );
};

The problem is: In ticket stack I need to decide which screen should I render. FYI: to navigate from drawer or any other higher navigator, I needed to give different name to Screen. Current implementation solves the problem that I have. But it smells, I know that there is a better solution for this but I can't find it. What is the best practice to achieve this? Instead of initialParams can I use different technique?


Solution

  • Based on react-navigation documentation, I'm doing the following for all my "conditional screen".

     <Stack.Navigator>
        {params?.yourConditionVariable ? (
          <Stack.Screen
            name="CustomerTickets"
            component={CustomerTicketsScreen}
          />
        ) : (
          <Stack.Screen name="Tickets" component={TicketsScreen} />
        )}
      </Stack.Navigator>
    

    It works pretty well, and it's the biggest feature of RN v5 on my side. I really love this flexibility!