Merig
Merig

Reputation: 2011

React Native Redux conditional rendering

I'm trying to render 2 different screens in my App based on the redux store status.

const App = () => {
    return (
        <Provider store={store}>
            <NavigationContainer ref={navigationRef}>
                {store.getState().auth.id ? (
                    <Home />
                ) : (
                    <Stack.Navigator screenOptions={HeaderStyles}>
                        <Stack.Screen
                            name='Splash'
                            component={Splash}
                            options={{ headerShown: false }}
                        />
                        <Stack.Screen name='SignUp' component={SignUp} />
                        <Stack.Screen name='Login' component={Login} />
                    </Stack.Navigator>
                )}
            </NavigationContainer>
        </Provider>
    );
};

At startup store.getState().auth.id is undefined, so the app correctly shows the Splash screen. In this screen, I set the auth.id in the store but the App doesn't rerender and stays in the Splash screen. If I save any source file without changing anything, if forces a rerender and I get correctly routed to Home.

How can I force the ternary operator to be evalued again when the store changes?

Upvotes: 1

Views: 148

Answers (1)

Hagai Harari
Hagai Harari

Reputation: 2877

At your file, store is imported from the file it is creating in, and not injected through props (mapState || useSelector). Because React re-render built on changes in props || state, the component doesn't know it should render again.

The easy way to go around the issue is to declare the conditional part at the child component and inject the redux state properly.

 <Provider store={store}>
            <NavigationContainer ref={navigationRef}>
               <Navigator />
            </NavigationContainer>
 </Provider>

   ....


const Navigator = () => { 
   let { id } = useSelector(state => state.auth)
   return !!id ? (
                    <Home />
                ) : (
                    <Stack.Navigator screenOptions={HeaderStyles}>
                        <Stack.Screen
                            name='Splash'
                            component={Splash}
                            options={{ headerShown: false }}
                        />
                        <Stack.Screen name='SignUp' component={SignUp} />
                        <Stack.Screen name='Login' component={Login} />
                    </Stack.Navigator>
                )
  }

Upvotes: 1

Related Questions