1

First i want to thank you for all answers.

I'm trying do Authentication Flow with React Navigation v6.x.

I want to catch in my App.js token value from AuthContext.js Because of new navigation version i'm looking for new way to create a AuthFlow. I see in Navigation documentation example for Authentication flow but there all logic be located in App.js and the whole thing is quite illegible.

I can take token from device but this solution dosent work with async changes. For example when i click SignIn button (signinscreen) it change token in mobile device but it refresh only singin screen.

App.js

import React, {useContext} from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import SigninScreen from './src/screens/SigninScreen';
import SignupScreen from './src/screens/SignupScreen';
import AccountScreen from './src/screens/AccountScreen';
import TrackListScreen from './src/screens/TrackListScreen';
import TrackDetailsScreen from './src/screens/TrackDetailsScreen';
import CreateTrackScreen from './src/screens/CreateTrackScreen';
import { Provider as AuthProvider } from './src/context/AuthContext';
import { Context as AuthContext } from './src/context/AuthContext';

const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();

const stackNestNav = () => {
  return(
    <Stack.Navigator>
      <Stack.Screen name="List" component={TrackListScreen} />
      <Stack.Screen name="Details" component={TrackDetailsScreen} />
    </Stack.Navigator>
  )
};

const AppNavigator = () => {
  return(
    <AuthProvider>
      <NavigationContainer>
            {token === null ? (
                <>
                <Stack.Navigator  screenOptions={{headerShown: false}}>
                  <Stack.Screen name="SignIn" component={SigninScreen} />
                  <Stack.Screen name="SignUp" component={SignupScreen} />
                </Stack.Navigator>
                </>
              ) : (
                <>
                <Tab.Navigator>
                  <Tab.Screen name="Track List" component={stackNestNav} options={{ headerStyle: {height: 0}}}/>
                  <Tab.Screen name="Create" component={CreateTrackScreen} />
                  <Tab.Screen name="Account" component={AccountScreen} />
                </Tab.Navigator>
                </>
              )
            }
      </NavigationContainer>
    </AuthProvider>
  )
}

export default AppNavigator;

and AuthContext.js

import AsyncStorage from '@react-native-async-storage/async-storage';
import createDataContext from './createDataContext';
import trackerApi from '../api/tracker';

const authReducer = (state,action) => {
    switch(action.type){
        case 'sign_error':
            return {...state, errorMessage: action.payload}
        case 'success_sign':
            return {errorMessage: '', token: action.payload}
        case 'clear_error_message':
            return {...state, errorMessage: ''}
        default:
            return state;
    }
};

//Czyszczenie wiadomości błędu
const clear_error_message = (dispatch) => () => {
    dispatch({ type: 'clear_error_message' })
}

//Rejestracja
const signup = (dispatch) => async({email,password}) => {
        try{
            const response = await trackerApi.post('/signup', {email,password});
            await AsyncStorage.setItem('token',response.data.token);

            dispatch({ type: 'success_sign', payload: response.data.token });
            console.log('Rejestracja przebiegła pomyślnie!');

        } catch (err) {
            dispatch({ type: 'sign_error', payload: 'Próba rejestracji nieudana.' })
        }
    };

//Logowanie
const signin = (dispatch) => async({email,password}) => {
        try {
            const response = await trackerApi.post('/signin', {email,password});
            await AsyncStorage.setItem('token',response.data.token);
            dispatch({ type: 'success_sign', payload: response.data.token });
            console.log('Logowanie przebiegło pomyślnie.');

        } catch (err) {
            dispatch({ type: 'sign_error', payload: 'Próba logowania nieudana.' });
            console.log(err.message);
        }
    };

//Wyloguj
const signout = (dispatch) => {
    return({email,password}) => {

    }
};

export const {Provider,Context} = createDataContext(
    authReducer,
    {signup,signin,signout,clear_error_message},
    { token: null, errorMessage: ''}
)

It is possible or should i do Context in App.js like in https://reactnavigation.org/docs/auth-flow?

One more time, thank you! :)

Jacob
  • 11
  • 2

1 Answers1

0

Solved.

  1. exported whole NavigatoContainer content to the other Component.
  2. created function in Context what catch token from mobile device and via dispatch updated state
  3. in componen with whole NavigatoContainer content used state and function from point 2.

Cya!

Jacob
  • 11
  • 2
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 03 '21 at 02:12