Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6211

How to manage UX auth error with react-native?

$
0
0

I setup a basic auth system following the react-navigation auth flow guide with FeathersJS react-native client.

Here is my main index.tsx file:

import 'react-native-gesture-handler';import React, {  useReducer, useEffect, useMemo, ReactElement,} from 'react';import { Platform, StatusBar } from 'react-native';import { NavigationContainer } from '@react-navigation/native';import { AppLoading } from 'expo';import { useFonts } from '@use-expo/font';import SplashScreen from './screens/SplashScreen';import { AuthContext } from './contexts';import { client } from './utils';import DrawerNavigator from './navigation/DrawerNavigator';import LogonStackNavigator from './navigation/LogonStackNavigator';interface State {  isLoading: boolean;  isSignOut: boolean;  userToken: string|null;}const App = (): ReactElement => {  /* eslint-disable global-require */  const [fontsLoaded] = useFonts({'Lato-Regular': require('../assets/fonts/Lato-Regular.ttf'),'Lato-Bold': require('../assets/fonts/Lato-Bold.ttf'),'Poppins-Light': require('../assets/fonts/Poppins-Light.ttf'),'Poppins-Bold': require('../assets/fonts/Poppins-Bold.ttf'),  });  /* eslint-enable global-require */  const [state, dispatch] = useReducer(    (prevState: State, action): State => {      switch (action.type) {        case 'RESTORE_TOKEN':          return {            ...prevState,            userToken: action.token,            isLoading: false,          };        case 'SIGN_IN':          return {            ...prevState,            isSignOut: false,            userToken: action.token,          };        case 'SIGN_OUT':          return {            ...prevState,            isSignOut: true,            userToken: null,          };        default:          return prevState;      }    },    {      isLoading: true,      isSignOut: false,      userToken: null,    },  );  useEffect(() => {    const bootstrapAsync = async (): Promise<void> => {      let userToken;      try {        const auth = await client.reAuthenticate();        console.log('reAuthenticate:', auth);        userToken = auth.accessToken;      } catch (e) {        // eslint-disable-next-line no-console        console.log('reAuthenticate failure:', e);      }      dispatch({        type: 'RESTORE_TOKEN',        token: userToken,      });    };    bootstrapAsync();  }, []);  const authContext = useMemo(    () => ({      signIn: async (data) => {        // In a production app, we need to send some data (usually username, password) to server and get a token        // We will also need to handle errors if sign in failed        // After getting token, we need to persist the token using `AsyncStorage`        // In the example, we'll use a dummy token        // eslint-disable-next-line no-console        console.log('signIn', data);        try {          const auth = await client.authenticate({            strategy: 'local',            ...data,          });          console.log(auth);          dispatch({            type: 'SIGN_IN',            token: 'dummy-auth-token',          });        } catch (e) {          console.log('signIn failure:', e);        }      },      signOut: async () => {        try {          await client.logout();          dispatch({ type: 'SIGN_OUT' });        } catch (e) {          console.log('signOut failure:', e);        }      },      signUp: async (data) => {        // In a production app, we need to send user data to server and get a token        // We will also need to handle errors if sign up failed        // After getting token, we need to persist the token using `AsyncStorage`        // In the example, we'll use a dummy token        // eslint-disable-next-line no-console        console.log('signUp', data);        dispatch({          type: 'SIGN_IN',          token: 'dummy-auth-token',        });      },    }),    [],  );  if (!fontsLoaded) {    return <AppLoading />;  }  if (state.isLoading) {    return <SplashScreen />;  }  return (<AuthContext.Provider value={authContext}>      {Platform.OS === 'ios'&& (<StatusBar barStyle="dark-content" />      )}      {state.userToken == null ? (<NavigationContainer><LogonStackNavigator /></NavigationContainer>      ) : (<NavigationContainer><DrawerNavigator /></NavigationContainer>      )}</AuthContext.Provider>  );};export default App;

And my SiginScreen.tsx file which handle the login form:

import React, { ReactElement } from 'react';import { StyleSheet, KeyboardAvoidingView } from 'react-native';import { StackNavigationProp } from '@react-navigation/stack';import { RouteProp } from '@react-navigation/core';import { AuthContext } from '../contexts';import {  LogonHeader, Button, Input, Text, TextLink,} from '../components';import { LogonStackParamList } from '../navigation/LogonStackNavigator';interface Props {  navigation: StackNavigationProp<LogonStackParamList, 'SignIn'>;  route: RouteProp<LogonStackParamList, 'SignIn'>;}const SignInScreen = ({ navigation }: Props): ReactElement => {  const [email, setEmail] = React.useState('');  const [password, setPassword] = React.useState('');  const { signIn } = React.useContext(AuthContext);  return (<KeyboardAvoidingView      style={styles.container}      behavior="padding"><LogonHeader title="Se connecter" /><Input        placeholder="E-mail"        value={email}        onChangeText={setEmail}        keyboardType="email-address"      /><Input        placeholder="Mot de passe"        value={password}        onChangeText={setPassword}        secureTextEntry      /><Button        title="Connexion"        onPress={() => signIn({          email,          password,        })}      /></KeyboardAvoidingView>  );};export default SignInScreen;

It works as expected, but I can't figure out how to handle the error case.

Currently, it's just a console.log statement on index.tsx file.

How can I properly informs the SignInScreen component that the logins fail to show a message at the user end? Should I use redux or something?

More exactly: I would like to put an error text message directly on SignInScreen in case of failure.


Viewing all articles
Browse latest Browse all 6211

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>