Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log In Screen #14

Closed
ziv-caspi opened this issue Jan 23, 2022 · 10 comments
Closed

Log In Screen #14

ziv-caspi opened this issue Jan 23, 2022 · 10 comments

Comments

@ziv-caspi
Copy link

What is the correct way of implementing a login screen in this template?
I have tried storing the logged in user in a store, and using a conditional render in the RootNavigator but I am having errors.

// Root Navigator
export const RootNavigator: React.FC =  observer(({}) => {
  const {auth} = useStores();
  console.log('regenrated', auth.currentUser);
  if (auth.currentUser != null)
  {
    return genRootNavigator(TabNavigator, [modals.ExampleModal]);
  }
  else
  {
    return LoginStack();
  }
});
@emrahc
Copy link

emrahc commented Jan 24, 2022

Try to render conditional routes in the "genRootNavigator" function.

@kanzitelli
Copy link
Owner

Hey, it's not recommended to add any logic inside gen...Navigator functions and Navigators itself (which are located in src/screens/index.ts), they should be as dumb as possible.

Better way would be to describe AuthNavigator (for example) in src/screens/index.ts and toggle AuthNavigator and RootNavigator in src/app.tsx depending on auth state.

// src/screens/index.ts

export const AuthNavigator = (): JSX.Element =>
  genStackNavigator([screens.Login, screens.Registration, screens.ForgotPassword]);
// src/app.tsx

export const AppNavigator = observer(() => {
  useColorScheme();
  const {nav} = useServices();
  const {auth} = useStores();

  return (
    <>
      <StatusBar barStyle={getThemeStatusBarStyle()} backgroundColor={getThemeStatusBarBGColor()} />
      <NavigationContainer
        ref={nav.n}
        onReady={nav.onReady}
        onStateChange={nav.onStateChange}
        theme={getNavigationTheme()}
      >
        {!!auth.currentUser ? <RootNavigator /> : <AuthNavigator />}
      </NavigationContainer>
    </>
  );
});

Or there is also the other way - you can describe AuthNavigator as above and just show it as a modal without messing toggling navigators.

Whatever works better for you.

@nykolaslima
Copy link

@kanzitelli after the successful login, how can I redirect to a screen in the RootNavigator?

@kanzitelli
Copy link
Owner

hey @nykolaslima! Could you elaborate more on your use case? I have a possible solution in mind but maybe yours is something different.

@nykolaslima
Copy link

nykolaslima commented Apr 3, 2022

Thanks for the fast response @kanzitelli !

I'm pretty new to react/react native, so maybe it's quite simple to solve.

I've implemented your suggested solution and after the successful login I'm trying to redirect to the Main screen:

const loginResponse: SuccessfulLoginResponse = data?.loginUser;
const token: string = loginResponse.token;
const refreshToken: string = loginResponse.refreshToken;
const user: User = loginResponse.user;
auth.setLoggedUser(user, token, refreshToken);
nav.push('Main');

And I get the following error:

The action 'PUSH' with payload {"name":"Main"} was not handled by any navigator.

Do you have a screen named 'Main'?

If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.

The navigators were configured this way:

const TabNavigator = () => genTabNavigator([tabs.Main, tabs.WIP, tabs.Settings]);

export const AuthNavigator = (): JSX.Element => genStackNavigator([screens.Login]);

// Root Navigator
export const RootNavigator = (): JSX.Element =>
  genRootNavigator(TabNavigator, [modals.ExampleModal]);
<>
      <StatusBar barStyle={getThemeStatusBarStyle()} backgroundColor={getThemeStatusBarBGColor()}/>
      <NavigationContainer
        ref={nav.n}
        onReady={nav.onReady}
        onStateChange={nav.onStateChange}
        theme={getNavigationTheme()}
      >
        {!!auth.currentUser ? <RootNavigator /> : <AuthNavigator />}
      </NavigationContainer>
    </>

What am I missing here?

@kanzitelli
Copy link
Owner

@nykolaslima no problem! I just like checking GitHub on Sunday night 😁

So from what I can see, you don't need to do nav.push('Main') because <RootNavigator /> will automatically show tabs.Main navigator as it is the first element of the tabs array in TabNavigator.

Make sure that you set auth.currentUser in your auth.setLoggedUser(...) method.

Let me know how it goes!

@nykolaslima
Copy link

I tried this and if the app is reloaded (closing it and opening again) then the RootNavigator is shown with the expected tabs. But after clicking into the login button and setting the auth.currentUser the screen is not "reloaded" with the RootNavigator

@kanzitelli
Copy link
Owner

@nykolaslima is your AppNavigator wrapped with mobx’s observer(…) function?

@nykolaslima
Copy link

mobx’s observer

It worked with the observer in the AppNavigator:

export const AppNavigator = observer((): JSX.Element => {
  useColorScheme();
  const {nav} = useServices();
  const {auth} = useStores();

  return (
    <>
      <StatusBar barStyle={getThemeStatusBarStyle()} backgroundColor={getThemeStatusBarBGColor()}/>
      <NavigationContainer
        ref={nav.n}
        onReady={nav.onReady}
        onStateChange={nav.onStateChange}
        theme={getNavigationTheme()}
      >
        {!!auth.currentUser ? <RootNavigator /> : <AuthNavigator />}
      </NavigationContainer>
    </>
  );
});

Thank you very much @kanzitelli :)

@kanzitelli
Copy link
Owner

@nykolaslima awesome, glad it helped! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants