0
votes

I would like to get some opinions on how you guys go about dynamically navigating your apps based on side effects.

Example:
LoginScreen - user enters email/pw and submits. I'm using Sagas to handle my side effects so when the user is successfully authenticated from the api and my Redux store is updated accordingly, I want to advance my user to the HomeScreen.

Solution 1:
With React Navigation tied to Redux I can dispatch a navigation call from my Saga that handles my login request/response. While this seems easiest, it also seems like it could get out of hand with having navigation spread throughout components and sagas, etc.

Solution 2:
Keep all navigation calls at the component level and upon prop updates from Redux, react accordingly and navigate forward based on the user object.

Are there any patterns or best practices for handling this in React Native with Redux and middleware(Sagas or Thunks)?

2

2 Answers

4
votes

Currently doing this with thunks, however it's all dependent on how you set up the loginState.

My loginState looks like this.

interface LoginState {
  authenthicated: boolean
  logging: boolean
  error: string
  key: string
}

Login thunk looks look this https://gist.github.com/iRoachie/7b6d5f33d9c9c8385f6f47822e7cea2f.

If the login succeeded, then I set the authenticated: true in the reducer. Then on my Login screen which is connected to redux, I use componentDidUpdate to check if authenticated === true, then navigate to the main screen.

if (this.props.loginState.authenthicated === true) {
  this.props.navigation.dispatch(
    NavigationActions.reset({
      index: 0,
      actions: [NavigationActions.navigate({ routeName: 'Main' })],
    })
  )
}

I always use it to manage the loading screen, but that's basically it.

1
votes

It's often easier to handle authentication with an encapsulating component. For example, in your routes:

<Route path="/" component={Auth}>
...
</Route>

Then your Auth component would look something like:

class Auth extends React.Component {
  render() {
    // Show children if user is authenticated
    if (this.props.authenticated) {
      return this.props.children;
    }

    // Show login component/screen if user is not authenticated
    return (
      <Login/>
    );
  }
}

The Auth component would be connected to your Redux store to set the authenticated property appropriately from the current state.

This has a number of advantages as you don't need to worry about navigating about. It's also easy to support the user loading your application from deep URLs (e.g. /something/else, not just /) and the relevant route will be automatically displayed once the user is successfully authenticated.