'React Native: How to handle protected routes with react navigation

What I want is to protect specific screens where the user can run specific actions and only at that point redirect him to a login screen, if the user is successfully authenticated, redirect him to the point where he left off the flow.

We can do this in React JS(with react-router), so I would like to know if its posible to implement a similar solution for react-native(with react-navigation):

React JS approach with React Router

function RequireAuth({ children }) {
  const { authed } = useAuth();
  const location = useLocation();

  return authed === true ? (
    children
  ) : (
    <Navigate to="/login" replace state={{ path: location.pathname }} />
  );
}


Solution 1:[1]

This is possible in react native and is documented in the authentication workflow section of the documentation.

In summary we conditionally need to render screens inside the navigator. Here is a minimal example using a Stack.Navigator which is similar to your posted code snippet. The workflow is identical for other navigators (nested or not). I will use the context api in my example, but there are other ways to achieve the same as well. The overall pattern is the same.

const AppContext = React.createContext()

function App() {

  const [isSignedIn, setIsSignedIn] = React.useState(false)

  const appContextValue = useMemo(
    () => ({
      isSignedIn,
      setIsSignedIn,
    }),
    [isSignedIn]
  )
    return (
     <AppContext.Provider value={appContextValue}>
      <Stack.Navigator>
        {!isSignedIn ? (
          <Stack.Screen
            name="Login"
            component={LoginScreen}
          />
          ) : (
          // whatever screens if user is logged in
          <Stack.Screen name="Home" component={HomeScreen} />
        )}
       </Stack.Navigator>
    </AppContext.Provider>
);

In the LoginScreen, you then need to change the authed state to true if the login was successful. The first screen in the conditional will then be initially rendered automatically (in this case HomeScreen).

function LoginScreen() {
   const { setIsSignedIn } = useContext(AppContext)

   // do whatever, then setIsSignedIn to true
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1