Skip to content Skip to sidebar Skip to footer

React Navigation After Login Navigate Problem

I'm using useNavigation in React Navigation. After logging in with AsyncStorage, I want to redirect to the home page, but I cannot go back to the App function. When I want to go to

Solution 1:

If you are using mobx for state management, create and manage signedIn state in your mobx state tree. when user logs in , you just have to set signedIn state to true. When user logs out, set signedIn to false. No need to use navigation props. When you change your signedIn state, react-navigation component will rerender.

Solution 2:

From the docs:

It's important to note that when using such a setup, you don't need to manually navigate to the Home screen by calling navigation.navigate('Home') or any other method. React Navigation will automatically navigate to the correct screen when isSigned in changes - Home screen when isSignedIn becomes true, and to SignIn screen when isSignedIn becomes false. You'll get an error if you attempt to navigate manually.

https://reactnavigation.org/docs/auth-flow/

So just remove the line:

navigation.navigate('HomeScreen');

And replace it with:

setSignedIn(true)

Or the MobX equivalent if you use MobX.

Solution 3:

You can try like this

return (
    <NavigationContainer>
      {signedIn != null ? (
        <Stack.NavigatorscreenOptions={{headerShown:false}}><Stack.Screenname="HomeScreen"component={_homeScreen} /></Stack.Navigator>
      ) : (
        <Stack.NavigatorscreenOptions={{headerShown:false}}><Stack.Screenname="WelcomeScreen"component={_welcomeScreen} /><Stack.Screenname="RegisterScreen"component={_registerScreen} /><Stack.Screenname="LoginScreen"component={_loginScreen} /><Stack.Screenname="ForgotScreen"component={_forgotScreen} /><Stack.Screenname="EmailCodeScreen"component={_emailCodeScreen} /></Stack.Navigator>
      )}
    </NavigationContainer>
  );

Solution 4:

First of all you cant use NavigationContainer twice..I would suggest make two Navigator like this one Login and another AppStack like this! I would just use redux and redux persist with async storage,makes life easier

constApp = () => {
  useEffect(() => {
    setTimeout(() => {
      RNBootSplash.hide({fade: true});
    }, 1000);
  }, []);

constLoginStack = () => {
  return (
    <Stack.Navigator><Stack.Screenname="Login"component={Login}options={{headerTransparent:true,

          cardStyle: {backgroundColor:colors.BACKGROUND},
          ...TransitionPresets.ModalSlideFromBottomIOS,
          headerTitleStyle: {color: 'transparent'},
        }}
      /><Stack.Screenname="Terms"component={Terms}options={{headerTransparent:true,

          cardStyle: {backgroundColor:colors.BACKGROUND},
          ...TransitionPresets.ModalPresentationIOS,
          headerTitleStyle: {color: 'transparent'},
        }}
      /></Stack.Navigator>
  );
};

constAppStack = () => {
  return (
    <Stack.Navigator>
      {screens.map((screen, i) => (
        <Stack.Screenname={screen.name}component={screen.screenname}key={i}options={{headerTransparent:true,

            cardStyle: {backgroundColor:colors.BACKGROUND},
            ...TransitionPresets.ModalSlideFromBottomIOS,
            headerTitleStyle: {color: 'transparent'},
          }}
        />
      ))}
    </Stack.Navigator>
  );
};
    
  constAppState = () => {
    const checkLoggedIn = useSelector((state) => state.AuthReducer.loggedIn);
    return<>{checkLoggedIn === false ? <LoginStack /> : <AppStack />}</>;
  };
  return (
    <Providerstore={store}><NavigationContainer><AppState /></NavigationContainer></Provider>
  );
};

store.js

import {applyMiddleware, createStore} from'redux';
import thunk from'redux-thunk';
importAsyncStoragefrom'@react-native-async-storage/async-storage';
import {persistStore, persistReducer} from'redux-persist';

import rootReducer from'./index';

// Middleware: Redux Persist Configconst persistConfig = {
  // Rootkey: 'root',
  // Storage Method (React Native)storage: AsyncStorage,
  // Whitelist (Save Specific Reducers)whitelist: ['StickerReducer', 'AuthReducer'],
  // Blacklist (Don't Save Specific Reducers)blacklist: [''],
};
// Middleware: Redux Persist Persisted Reducerconst persistedReducer = persistReducer(persistConfig, rootReducer);

const middleware = [thunk];

const store = createStore(persistedReducer, applyMiddleware(...middleware));

// Middleware: Redux Persist Persisterlet persistor = persistStore(store);
// Exportsexport {store, persistor};

Auth Reducer

import {ADD_DEVICE_TOEKN, LOGGED_IN} from'./types';

const initialState = {
  loggedIn: false,
  user_Id: '',
  device_token: '',
};

exportdefaultAuthReducer = (state = initialState, action) => {
  switch (action.type) {
    caseLOGGED_IN:
      const paylodLoggedIn = action.payload;
      return {
        ...state,
        loggedIn: paylodLoggedIn.loggedIn,
        user_Id: paylodLoggedIn.loggedIn,
      };
    caseADD_DEVICE_TOEKN:
      const paylodToken = action.payload;
      return {
        ...state,
        device_token: paylodToken,
      };
    default:
      return state;
  }
};

import {combineReducers} from'redux';
importAuthReducerfrom'./AuthReducer';
importStickerReducerfrom'./StickerReducer';

exportdefaultcombineReducers({
  AuthReducer: AuthReducer,
  StickerReducer: StickerReducer,
});

Authaction.js

import {LOGGED_IN} from'../types';

exportconstLoginAction = (userData) => {
  return(dispatch) => {
    dispatch({
      type: LOGGED_IN,
      payload: userData,
    });
  };
};

Finally login dispacther

import {useDispatch} from'react-redux';
import {LoginAction} from'../../../redux/actions/LoginAction';
constLogin = ({navigation}) => {
  const dispatch = useDispatch();
 return (
<PressableonPress={() =>dispatch(LoginAction(data))}>
  </Pressable>
    );
    };

Solution 5:

If you wanna trigger the App.js after successfull login ... then You need to wrap your NavigationContainer with React.Context

Your signedIn user is an object I think ... not an array so by initalizing it in state with [] ... if(signedIn != null) will never evaluate to true ++ Make sure you JSON.parse your object after fetching it from AsyncStorage ...

constAuthContext = React.createContext({
    signedIn,
    _checkUser: () => {},
  });
  
  exportconstuseAuth = () => React.useContext(AuthContext);

  const defaultValue = {
    signedIn,
    _checkUser,
  };

  return (
    <AuthContext.Providervalue={defaultValue}><NavigationContainer><Stack.NavigatorscreenOptions={{headerShown:false }}>
          {signedIn ? (
            <Stack.Screenname="HomeScreen"component={_homeScreen} />
          ) : (
            <><Stack.Screenname="WelcomeScreen"component={_welcomeScreen} /><Stack.Screenname="RegisterScreen"component={_registerScreen} /><Stack.Screenname="LoginScreen"component={_loginScreen} /><Stack.Screenname="ForgotScreen"component={_forgotScreen} /><Stack.Screenname="EmailCodeScreen"component={_emailCodeScreen}
              /></>
          )}
        </Stack.Navigator></NavigationContainer>
    </AuthContext.Provider>
  );

In LoginScreen

// Then you refresh you auth user in LoginScreen likeconst { _checkUser } = useAuth();
  _checkUser();

Post a Comment for "React Navigation After Login Navigate Problem"