Search code examples
react-nativereact-hooksuse-reducerreact-usememo

React Navigation v5 Authentication Flows (Screens as Different Files)


If we see in the doc example: https://reactnavigation.org/docs/auth-flow/ :

function SignInScreen() {
  const [username, setUsername] = React.useState('');
  const [password, setPassword] = React.useState('');

  const { signIn } = React.useContext(AuthContext); // ????

  return (
    <View>
      <TextInput
        placeholder="Username"
        value={username}
        onChangeText={setUsername}
      />
      <TextInput
        placeholder="Password"
        value={password}
        onChangeText={setPassword}
        secureTextEntry
      />
      <Button title="Sign in" onPress={() => signIn({ username, password })} />
    </View>
  );
}

SignInScreen is located in the same App.js. If we put out SignInScreen as a new file SignInScreen.js, how to dispatch the signIn from SignInScreen.js?


Solution

  • You must have a wrapper for SignInScreen

    // App.js
    import SignInScreen from '...'
    
    // Export the context
    export const AuthContext = React.createContext();
    
    export default function App() {
      // ... some bootstrap code
      // https://reactnavigation.org/docs/auth-flow/#implement-the-logic-for-restoring-the-token
      const authContext = React.useMemo(
        () => ({
          signIn: async (data) => { ... },
        }),
        []
      );
    
      return (
        <AuthContext.Provider value={authContext}>
          <SignInScreen />
        </AuthContext.Provider>
      );
    }
    
    import { AuthContext } from "./App.js"
    
    function SignInScreen() {
      // Must be child of AuthContext.Provider
      const { signIn } = React.useContext(AuthContext);
    
      return (
        <View>
          ...
        </View>
      );
    }